<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://archonwiki.slitherine.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Phil</id>
	<title>Archon Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://archonwiki.slitherine.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Phil"/>
	<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php/Special:Contributions/Phil"/>
	<updated>2026-06-07T12:18:54Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.2</generator>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=601</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=601"/>
		<updated>2026-05-13T20:14:05Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* 3DOBJECT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
DRAGLIMIT               // limit the draggable object to the screen bounds during dragging&lt;br /&gt;
DRAGGABLEBY             // values can be 1 (LMB), 2 (RMB), or 3 (both)&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based (from VALUE0). Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 3DOBJECT ====&lt;br /&gt;
&lt;br /&gt;
A generic 3D object that is rendered to the center of the screen.  It can have an animation file in the standard format.&lt;br /&gt;
This is picked on only the mesh, so the defined bounds in the UI file are ignored.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
TEXPATH &amp;lt;path&amp;gt; - set the path that textures should be loaded from&lt;br /&gt;
ANIM &amp;lt;animName&amp;gt; - set a start anim for the object to play&lt;br /&gt;
LOOPANIM - loop the animation&lt;br /&gt;
SCALE - additional scale applied to the object on rendering&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Command that can be used:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
SetUIObject3DAnim&lt;br /&gt;
SetUIObject3DShaderValues&lt;br /&gt;
UIObject3DLoad&lt;br /&gt;
&lt;br /&gt;
// places the name of the last mesh (or submesh) in the object that was picked into a working string (default index 0)&lt;br /&gt;
GetUIObject3DLastPicked(objectName [, stringIndex])&lt;br /&gt;
&lt;br /&gt;
//set a texture on a 3DObject. Uses default texture path as per loading. If submesh named then only that submesh texture is changed&lt;br /&gt;
SetUI3DObjectTexture(objectName, textureFile, [texturePath], [submeshName])&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Hotkeys&amp;diff=600</id>
		<title>Empires Hotkeys</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Hotkeys&amp;diff=600"/>
		<updated>2026-04-27T15:57:49Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Shift+F11 - open script debugger&lt;br /&gt;
* Shift+F12 - toggle object inspector&lt;br /&gt;
* F - cycle through terrain display modes (normal, hide FOW effect, hide weather effect, hide both)&lt;br /&gt;
* Ctrl+Shift+A - rerun the AI for the current turn&lt;br /&gt;
* Shift+Home - toggle script profiler&lt;br /&gt;
* Shift+End - reset script profiler&lt;br /&gt;
* Ctrl+F11 - reload shaders, edit and continue supported&lt;br /&gt;
* Ctrl+F12 - reload scripts, edit and continue supported&lt;br /&gt;
* Ctrl+Home - reload textures which have changes since loading&lt;br /&gt;
* Ctrl+End - reload UI and string files&lt;br /&gt;
* PrtScn - take a screenshot (saved in My Games\FieldOfGloryEmpires\SCREENS)&lt;br /&gt;
* Ctrl+Shift+P - start or stop recording a video (slideshow)&lt;br /&gt;
&lt;br /&gt;
Many dev hotkeys require debug mode to be active&lt;br /&gt;
&lt;br /&gt;
See Key Mapping in the game Options UI for more keys.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Scripting&amp;diff=599</id>
		<title>Scripting</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Scripting&amp;diff=599"/>
		<updated>2026-04-20T21:20:18Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Singletons */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Archon scripting is a much expanded iteration on the original STUB scripting.  The original documentation is included/updated below.&lt;br /&gt;
&lt;br /&gt;
== Script Syntax ==&lt;br /&gt;
&lt;br /&gt;
CScript is a simple scripting language, based on the basic C syntax. It provides a simple framework to hook it up to an application, effectively the function call handling.&lt;br /&gt;
&lt;br /&gt;
Even if you have not had experience with scripting languages before, you can begin to add or alter your custom scripts using just a simple text editor (see the Tools section for details on how to help make editing better with syntax highlighting and other useful features).&lt;br /&gt;
&lt;br /&gt;
The team recommend taking a look at the existing scripts to begin to see the way the scripting works. Beginning by tweaking existing scripts is a great way to see something onscreen quickly.&lt;br /&gt;
&lt;br /&gt;
All scripting must be part of a function. A function has the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;FUNCTION &amp;lt;name&amp;gt;( [&amp;lt;param&amp;gt;], [&amp;lt;param&amp;gt;], ...)&lt;br /&gt;
 {&lt;br /&gt;
 	&amp;lt;function body&amp;gt;&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;FUNCTION Tick( side ) &lt;br /&gt;
 {&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;FUNCTION Process( TType data )&lt;br /&gt;
 {&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is a limit of 12 parameters that can be passed to a given function.&lt;br /&gt;
&lt;br /&gt;
All functions return a value, although you do not have to use it, nor use the return should you decide not to. To return a value use:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;return &amp;lt;value&amp;gt; ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that a call to return will skip any further processing in the function and exit with the value immediately.&lt;br /&gt;
&lt;br /&gt;
=== Macros ===&lt;br /&gt;
&lt;br /&gt;
You can define macros - textual substitutions - in the same way as for C.  Note that #/## notations are not supported.  E.g.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;#define MAX_UNITS 256&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Predefined Macros ====&lt;br /&gt;
&lt;br /&gt;
Some macros may be predefined based on other data files.  The names of these predefined macros will always begin with a $ character and all characters will be in uppercase.&lt;br /&gt;
* Macros will be predefined for all colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT that are appropriate for use where script commands expect colours as parameters.&lt;br /&gt;
* Macros will be predefined for all fonts specified in SYSTEM/FONT.TXT that are appropriate for use where script commands expect fonts as parameters.&lt;br /&gt;
&lt;br /&gt;
For example, &amp;lt;code&amp;gt;DrawMapString(x, y, $SMALLFONT, $ALERTCOLOUR)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structures ===&lt;br /&gt;
&lt;br /&gt;
You can define structures in a similar way to C.  The format is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;struct &amp;lt;typename&amp;gt;&lt;br /&gt;
 { &lt;br /&gt;
 	&amp;lt;contents&amp;gt;&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;struct TPos&lt;br /&gt;
 {&lt;br /&gt;
 	int x ;&lt;br /&gt;
 	int y ;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 struct TObject&lt;br /&gt;
 { &lt;br /&gt;
 	int type ;&lt;br /&gt;
 	TPos position ;&lt;br /&gt;
 	int orders[4] ;&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Access is as per standard C syntax:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;TObject obj ;&lt;br /&gt;
 &lt;br /&gt;
 obj.type = 5 ;&lt;br /&gt;
 obj.orders[0] = 0 ;&lt;br /&gt;
 obj.position.x = 9 ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Control ===&lt;br /&gt;
&lt;br /&gt;
You have 2 ways to control the flow of a function. The IF statement, and the FOR statement. All code executed by an IF or FOR statement must be enclosed in a block (within a { } pair).&lt;br /&gt;
&lt;br /&gt;
An IF statement has the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;if( &amp;lt;condition&amp;gt; )&lt;br /&gt;
 {&lt;br /&gt;
 	&amp;lt;execute if condition true&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 else if( &amp;lt;condition 2&amp;gt; )&lt;br /&gt;
 {&lt;br /&gt;
 	&amp;lt;execute if condition 2 true&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
 {&lt;br /&gt;
 	&amp;lt;execute if neither condition false&amp;gt;&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the else keyword and following code is optional. Where the condition can be made up of various logical operators such as &amp;amp;&amp;amp; (and) and || (or). So an example statement would be:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;if( ( a == 10) || ( b == 5 ) )&lt;br /&gt;
 {&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A FOR statement has the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;for(&amp;lt;start&amp;gt;; &amp;lt;condition&amp;gt;; &amp;lt;delta&amp;gt;)&lt;br /&gt;
 {&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;start&amp;gt; is a statement initialising the loop variable, &amp;lt;condition&amp;gt; is a check where the loop will continue so long as it is true, and the &amp;lt;delta&amp;gt; statement is a simple expression incrementing (or decrementing) the loop variable. So the statement:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;for( i=0; i&amp;lt;10; i++ )&lt;br /&gt;
 {&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
would repeat the code inside the block with i having values of 0 to 9 inclusive, before moving onto any following code.&lt;br /&gt;
&lt;br /&gt;
Key Differences with C&lt;br /&gt;
&lt;br /&gt;
+ There is no operator priority. Brackets are supported and their use recommended.&lt;br /&gt;
&lt;br /&gt;
+ IF statements can can use only a single &amp;amp;&amp;amp; or || statement pair when expressions are not contained in brackets. That is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;if( a == 0 &amp;amp;&amp;amp; b == 0 &amp;amp;&amp;amp; c == 0 )		is invalid&lt;br /&gt;
 &lt;br /&gt;
 if( (a == 0) &amp;amp;&amp;amp; (b == 0) &amp;amp;&amp;amp; (c == 0) )	is valid&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
+ All atomic variables are signed integers.&lt;br /&gt;
&lt;br /&gt;
+ Single line IF and FOR result expressions are not allowed:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;if(a == 0)							is invalid&lt;br /&gt;
 	a = 10 ;&lt;br /&gt;
 &lt;br /&gt;
 if(a == 0)							is valid&lt;br /&gt;
 {&lt;br /&gt;
 	a = 10 ;&lt;br /&gt;
 }&amp;lt;/code&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
+ All structures are passed by reference to functions (e.g. any changes to a passed in struct in a function will affect the passed in variable in the calling function).							&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Including Files ===&lt;br /&gt;
&lt;br /&gt;
You can include other files in your scripts. These can contain useful utility functions, either of your own, or from the game. The syntax for including a file is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;include &amp;quot;filename.bsf&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(note that #include will work also)&lt;br /&gt;
&lt;br /&gt;
The script system will look for the file in the following places in the following order:&lt;br /&gt;
&lt;br /&gt;
 same folder as the initial file&lt;br /&gt;
 &amp;lt;campaign folder&amp;gt;/DATA/BATTLE/SCRIPTS&lt;br /&gt;
 &amp;lt;campaign folder&amp;gt;/DATA/SCRIPTS&lt;br /&gt;
 DATA/BATTLE/SCRIPTS&lt;br /&gt;
 DATA/SCRIPTS&lt;br /&gt;
 filename as provided&lt;br /&gt;
&lt;br /&gt;
=== Singletons ===&lt;br /&gt;
&lt;br /&gt;
Any variables defined outside a function are considered to be global, singleton variables.  These variables are a single instance across all scripts that access them.  You can also initialise singletons (but not local variables) this initialiser lists.  These should exactly match the number of entries, and do not support sub-lists.  E.g.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;int gArray[3][2]={0,1,2,3,4,5} ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use a const tag.  This means that these variables will not be cleared to zero when loading script state.  They WILL, however, be overwritten if there is data stored in the savegame.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;const int gConstArray[3][2]={0,1,2,3,4,5} ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The char Type ===&lt;br /&gt;
&lt;br /&gt;
You can define and use arrays of chars as strings.  Versions of the sprintf and strcpy functions exist.  These functions are safe, in that they cannot exceed the bounds of their output strings.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;char name[32] ;&lt;br /&gt;
 char work[32] ;&lt;br /&gt;
 int someValue ;&lt;br /&gt;
 &lt;br /&gt;
 	someValue = 99 ;&lt;br /&gt;
 	name[0] = 'A' ;&lt;br /&gt;
 	PrintStringLiteral( name ) ;&lt;br /&gt;
 	sprintf( work, &amp;quot;%d&amp;quot;, someValue ) ;&lt;br /&gt;
 	strcpy( name, work ) ;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Limitations to note:&lt;br /&gt;
&lt;br /&gt;
char arrays must be multiples of 4 in size, multidimensional arrays are supported.&lt;br /&gt;
&lt;br /&gt;
== The Debugger ==&lt;br /&gt;
There is an integrated script debugger which can be activated with &amp;lt;b&amp;gt;CTRL+F3&amp;lt;/b&amp;gt;.  This allows you to check variable values, flow, etc.  Note that the debugger is still work in progress.  You can insert a breakpoint into your code using the &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;DebugBreak;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
intrinsic, as well as dynamic breakpoints you set yourself in the code.&lt;br /&gt;
&lt;br /&gt;
=== User Watch List ===&lt;br /&gt;
To add an expression, type the expression in the edit box below the list, or you can hit W to add the current mouseover expression to the watch list.  DEL should delete an entry in the list.  The list is saved and loaded between sessions.&lt;br /&gt;
&lt;br /&gt;
Note that only expressions which evaluate to an integer or string are currently accepted (so you cannot enter an array element then explore it).  I am planning to improve this.&lt;br /&gt;
&lt;br /&gt;
When maximum script debugging is enabled (only on builds built to support this) then add a # to the start of the expresion.  E.g. to break on myBreakVar enter #myBreakVar into the editbox.  Note that this requires the DEBUGMODE value in USER.TXT to be 32 or 64 (64 enables CTRL+0 (zero) to break into a running script.  Enabling this causes a notable reduction in script performance.&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
=== For Loops ===&lt;br /&gt;
Some loop constructs will execute more quickly than others.  Specifically loops that are on a variable from a numeric start, with a less than test against either a numeric value or a simple variable, and a ++ increment.&lt;br /&gt;
&lt;br /&gt;
Faster&lt;br /&gt;
 for(i=0;i&amp;lt;10;i++)&lt;br /&gt;
 for(i=0;i&amp;lt;count;i++)&lt;br /&gt;
&lt;br /&gt;
Not faster&lt;br /&gt;
 for(i=0;i&amp;lt;=10;i+=1)&lt;br /&gt;
 for(i=x;i&amp;lt;array[7].count;i++)&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Updates&amp;diff=598</id>
		<title>Latest Updates</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Updates&amp;diff=598"/>
		<updated>2026-04-01T17:48:41Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Auto LOD =&lt;br /&gt;
The system can automatically generate LODs for map objects.&lt;br /&gt;
This is disabled if bit 0 of the SYSTEMFLAGS tweak is set to zero.&lt;br /&gt;
It can also be disabled by setting bit 0 of the GFXFlags option to 1.&lt;br /&gt;
Per-object control happens via an LOD tag in the relevant OBJECTS.TXT file entry.&lt;br /&gt;
 LOD -1    // disable LODing for this object&lt;br /&gt;
 LOD 0     // use the default calculations&lt;br /&gt;
 LOD &amp;lt;N&amp;gt;   // attempt to reduce this to N% of its face count (must be [1,100])&lt;br /&gt;
&lt;br /&gt;
= Command line handling =&lt;br /&gt;
Command line must start with CUSTOM  (that is CUSTOM followed by a space).  The rest of the command line is passed to the function CUSTOM_COMMAND() in LOADINIT.BSF with the custom command line in the first work string.  Note this is called after the LOADINIT function in the script, and after the main menu has come up (and in theory after any server messages etc).  Added partly as a first part for AGEOD integration, and also could be hooked up to the player-driven campaign game app from the forums.&lt;br /&gt;
[I am sure there will be some foibles trying to kick off battles from the main menu, but this provides a starting point.]&lt;br /&gt;
Note: the max length of the command line is 768 characters (not including the CUSTOM&amp;lt;space&amp;gt; header).&lt;br /&gt;
&lt;br /&gt;
= Multiplayer UI Callbacks =&lt;br /&gt;
There are a number of callbacks for MP UI use&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION MULTIPLAYER_USERDATA_CALLBACK( [skirmish] )&lt;br /&gt;
{&lt;br /&gt;
	// this should fill the work array with up to 16 values&lt;br /&gt;
	// generally this would be driven by custom UI&lt;br /&gt;
	// these values are then available in the working array immediately after the battle loads&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FUNCTION MULTIPLAYER_USERDATA_TOOLTIP_CALLBACK( [skirmish])&lt;br /&gt;
{&lt;br /&gt;
	// this is called with the user data in the work array, and should fill the UI string with the appropriate tooltip&lt;br /&gt;
	// only adds a tooltip if it returns != 0&lt;br /&gt;
	return 1 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FUNCTION MULTIPLAYER_USERDATA_ACCEPT_CALLBACK( [skirmish, side] )&lt;br /&gt;
{&lt;br /&gt;
	// this is called with the user data in the work array&lt;br /&gt;
	// if returns 0 then no side string is shown in the accept list&lt;br /&gt;
	// if returns !=0 then appends the contents of the first UI string to the list entry&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FUNCTION MULTIPLAYER_PROT_ACCEPT_CALLBACK( [skirmish, side, prot] )&lt;br /&gt;
{&lt;br /&gt;
	// this is called with the user data in the work array&lt;br /&gt;
	// the prot value is the bitfield passed from the challenge.  Note that the top bit is always set and should be ignored.&lt;br /&gt;
	// it should return the prot value based on the sides etc&lt;br /&gt;
	// this allows correct disabling of games that the user cannot play based on their DLC ownership&lt;br /&gt;
	// NOTE: if a game is accepted without the DLC being available it will still fail on battle start&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
{&lt;br /&gt;
	// Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
	// Place any string to be added in the first UI string&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
FUNCTION LOAD_USERDATA_CALLBACK( [skirmish] )&lt;br /&gt;
{&lt;br /&gt;
	// Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
	// skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= WriteScenarioFile =&lt;br /&gt;
This function can allow a scenario file to be created from the combination of a header string and the contents of a file.  The command looks for the file in &amp;lt;campaign&amp;gt;/DATA/SCRIPTS and then DATA/SCRIPTS.  It then creates a new .BSF file named for the scenario which is made up of the header followed by the contents of the template file.&lt;br /&gt;
&lt;br /&gt;
The calling script must handle overwrite confirms etc (if needed).&lt;br /&gt;
&lt;br /&gt;
 //create a scenario file for the current editor scenario. The file is the headerSource followed by the contents of the templateFilename file. If overwrite !=0 then will overwrite any existing file, otherwise not. Returns -1 (failed), 0 (exists), 1 success. See wiki for more details.&lt;br /&gt;
 WriteScenarioFile(templateFilename, headerSource, overwrite)&lt;br /&gt;
&lt;br /&gt;
The header can include (e.g.) globals or defines which are then referenced in the template script.&lt;br /&gt;
&lt;br /&gt;
= Editor Font Customisation =&lt;br /&gt;
You can now set up aliases for the fonts used in various modes for the main list (ScenEdTileList).  Aliases must be in the global chunk (at the top) of the font file.  They are of the form:&lt;br /&gt;
&lt;br /&gt;
 ALIAS &amp;lt;name&amp;gt;=&amp;lt;actualFont&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So an example (for the tile list in the editor) would be:&lt;br /&gt;
&lt;br /&gt;
 ALIAS SmoothFont_EdTileSet=MyEdTileFont&lt;br /&gt;
&lt;br /&gt;
Note you will get an error if the aliased font does not exist.  The currently defined aliases are&lt;br /&gt;
&lt;br /&gt;
 SmoothFont_EdTileSet&lt;br /&gt;
 SmallFont_EdObjSet&lt;br /&gt;
 Default_EdUnitSet&lt;br /&gt;
 Default_EdBonusSet&lt;br /&gt;
 Default_EdCarrySet&lt;br /&gt;
&lt;br /&gt;
If no alias is defined, then the base (pre-underscore) name will be used for the font (e.g. SmoothFont for SmoothFont_EdTileSet).&lt;br /&gt;
&lt;br /&gt;
= Load/Save and Options Layout =&lt;br /&gt;
If you include a screen whose root is called SystemMenu, then the default load/save etc functionality will be disabled somewhat.  ESC will open this SystemMenu, or close either the LoadSave, Options, or SystemMenu screen (whichever is at the top level).  This allows for finer control of the layout and use of the loadsave screens.&lt;br /&gt;
&lt;br /&gt;
Note, you can open a correctly set up loadsave or options screen by using custom command values 0 or 1 respectively.  E.g.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;COMMAND CUSTOM 1&amp;lt;/nowiki&amp;gt; attached to a button will open the options screen.&lt;br /&gt;
&lt;br /&gt;
= Unit Orientation =&lt;br /&gt;
If you include a TerrainFollow attrib in the squads file, then for units with this attrib as non-zero they will align themselves with the terrain (i.e. hills etc)&lt;br /&gt;
&lt;br /&gt;
= Formation Change =&lt;br /&gt;
All units now call the formation callback, not just those with more than 1 man remaining.&lt;br /&gt;
&lt;br /&gt;
= Editor Unit Loading =&lt;br /&gt;
Set the tweak EditorDefaultLoading to zero to require the CTRL key to load units onto other units.  For editor ease of use for games where units cannot carry other units.&lt;br /&gt;
&lt;br /&gt;
= Editor Unit Values =&lt;br /&gt;
You can now set up to 4 user values on units in the editor.  These are stored in 4 attribs called System_EditorData0 to System_EditorData3.  Users should set them onto the units in the editor in the usual way using SetAttrib.  To facilitate editor functionality the new script command GetEditorLastUnit() is available.&lt;br /&gt;
&lt;br /&gt;
= Editor Display Callback =&lt;br /&gt;
 &amp;lt;code&amp;gt;FUNCTION HELPER_UNIT_EDITOR_DISPLAY(side, unit)&amp;lt;/code&amp;gt;&lt;br /&gt;
This new function in the helper script is called for each unit on the map in the editor.  If it returns non-zero then the system will include the contents of the first UI string in the information that is shown over the unit (e.g. Fixed, Carryover, etc).&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=597</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=597"/>
		<updated>2026-04-01T17:42:35Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= (Tile) Auto LOD =&lt;br /&gt;
There is new documentation on the auto LOD feature in the tile version&lt;br /&gt;
[[Tile Turn Based Version]]&lt;br /&gt;
&lt;br /&gt;
= ELSEIFDEF and ELSEIFNDEF =&lt;br /&gt;
Added the ability to stack #IFDEF queries.  E.g.&lt;br /&gt;
 #IFDEF SOMETHING&lt;br /&gt;
 ...&lt;br /&gt;
 #ELSEIFDEF SOMETHING_ELSE&lt;br /&gt;
 ...&lt;br /&gt;
 #ELSEIFNDEF SOMETHING_NOT&lt;br /&gt;
 ...&lt;br /&gt;
 #ELSE&lt;br /&gt;
 ...&lt;br /&gt;
 #ENDIF&lt;br /&gt;
There is no limit to how many checks you can stack.&lt;br /&gt;
&lt;br /&gt;
= Added DRAGGABLEBY tag =&lt;br /&gt;
You can now drag objects using both the left and right mouse button, or both.&lt;br /&gt;
 DRAGGABLEBY &amp;lt;unsigned&amp;gt;&lt;br /&gt;
Where the value can be 1 (LMB only), 2 (RMB only), or 3 (both).&lt;br /&gt;
&lt;br /&gt;
= New functionality for 3DObject =&lt;br /&gt;
See UI docs here: [[UI#3DOBJECT|3DObject]]&lt;br /&gt;
&lt;br /&gt;
= New tabstop tag for string rendering =&lt;br /&gt;
See here [[UI#Strings|Strings]]&lt;br /&gt;
&lt;br /&gt;
= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=596</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=596"/>
		<updated>2026-04-01T17:37:26Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= ELSEIFDEF and ELSEIFNDEF =&lt;br /&gt;
Added the ability to stack #IFDEF queries.  E.g.&lt;br /&gt;
 #IFDEF SOMETHING&lt;br /&gt;
 ...&lt;br /&gt;
 #ELSEIFDEF SOMETHING_ELSE&lt;br /&gt;
 ...&lt;br /&gt;
 #ELSEIFNDEF SOMETHING_NOT&lt;br /&gt;
 ...&lt;br /&gt;
 #ELSE&lt;br /&gt;
 ...&lt;br /&gt;
 #ENDIF&lt;br /&gt;
There is no limit to how many checks you can stack.&lt;br /&gt;
&lt;br /&gt;
= Added DRAGGABLEBY tag =&lt;br /&gt;
You can now drag objects using both the left and right mouse button, or both.&lt;br /&gt;
 DRAGGABLEBY &amp;lt;unsigned&amp;gt;&lt;br /&gt;
Where the value can be 1 (LMB only), 2 (RMB only), or 3 (both).&lt;br /&gt;
&lt;br /&gt;
= New functionality for 3DObject =&lt;br /&gt;
See UI docs here: [[UI#3DOBJECT|3DObject]]&lt;br /&gt;
&lt;br /&gt;
= New tabstop tag for string rendering =&lt;br /&gt;
See here [[UI#Strings|Strings]]&lt;br /&gt;
&lt;br /&gt;
= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=595</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=595"/>
		<updated>2026-02-23T22:36:22Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Additional Common Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
DRAGLIMIT               // limit the draggable object to the screen bounds during dragging&lt;br /&gt;
DRAGGABLEBY             // values can be 1 (LMB), 2 (RMB), or 3 (both)&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based (from VALUE0). Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 3DOBJECT ====&lt;br /&gt;
&lt;br /&gt;
A generic 3D object that is rendered to the center of the screen.  It can have an animation file in the standard format.&lt;br /&gt;
This is picked on only the mesh, so the defined bounds in the UI file are ignored.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
TEXPATH &amp;lt;path&amp;gt; - set the path that textures should be loaded from&lt;br /&gt;
ANIM &amp;lt;animName&amp;gt; - set a start anim for the object to play&lt;br /&gt;
LOOPANIM - loop the animation&lt;br /&gt;
SCALE - additional scale applied to the object on rendering&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Command that can be used:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
SetUIObject3DAnim&lt;br /&gt;
SetUIObject3DShaderValues&lt;br /&gt;
UIObject3DLoad&lt;br /&gt;
&lt;br /&gt;
// places the name of the last mesh (or submesh) in the object that was picked into a working string (default index 0)&lt;br /&gt;
GetUIObject3DLastPicked(objectName [, stringIndex])&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=594</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=594"/>
		<updated>2026-02-23T22:35:26Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Added DRAGGABLEBY tag =&lt;br /&gt;
You can now drag objects using both the left and right mouse button, or both.&lt;br /&gt;
 DRAGGABLEBY &amp;lt;unsigned&amp;gt;&lt;br /&gt;
Where the value can be 1 (LMB only), 2 (RMB only), or 3 (both).&lt;br /&gt;
&lt;br /&gt;
= New functionality for 3DObject =&lt;br /&gt;
See UI docs here: [[UI#3DOBJECT|3DObject]]&lt;br /&gt;
&lt;br /&gt;
= New tabstop tag for string rendering =&lt;br /&gt;
See here [[UI#Strings|Strings]]&lt;br /&gt;
&lt;br /&gt;
= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=593</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=593"/>
		<updated>2026-02-23T22:33:52Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* new tabstop tag for string rendering */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= New functionality for 3DObject =&lt;br /&gt;
See UI docs here: [[UI#3DOBJECT|3DObject]]&lt;br /&gt;
&lt;br /&gt;
= New tabstop tag for string rendering =&lt;br /&gt;
See here [[UI#Strings|Strings]]&lt;br /&gt;
&lt;br /&gt;
= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=592</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=592"/>
		<updated>2026-01-30T17:44:58Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Additional Common Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
DRAGLIMIT               // limit the draggable object to the screen bounds during dragging&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based (from VALUE0). Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 3DOBJECT ====&lt;br /&gt;
&lt;br /&gt;
A generic 3D object that is rendered to the center of the screen.  It can have an animation file in the standard format.&lt;br /&gt;
This is picked on only the mesh, so the defined bounds in the UI file are ignored.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
TEXPATH &amp;lt;path&amp;gt; - set the path that textures should be loaded from&lt;br /&gt;
ANIM &amp;lt;animName&amp;gt; - set a start anim for the object to play&lt;br /&gt;
LOOPANIM - loop the animation&lt;br /&gt;
SCALE - additional scale applied to the object on rendering&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Command that can be used:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
SetUIObject3DAnim&lt;br /&gt;
SetUIObject3DShaderValues&lt;br /&gt;
UIObject3DLoad&lt;br /&gt;
&lt;br /&gt;
// places the name of the last mesh (or submesh) in the object that was picked into a working string (default index 0)&lt;br /&gt;
GetUIObject3DLastPicked(objectName [, stringIndex])&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=CSV_Validation&amp;diff=591</id>
		<title>CSV Validation</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=CSV_Validation&amp;diff=591"/>
		<updated>2026-01-12T19:38:26Z</updated>

		<summary type="html">&lt;p&gt;Phil: Created page with &amp;quot;== CSV Validation ==  Validation of CSV entries is as follows:  * For integer entries Only  [0,9]  -    (minus character) are allowed.  * For string and define entries By default only  [0,9]  [a,z]  [A,Z]  $    (dollar sign)  _    (underscore)  .    (period) are allowed.  But you can expand this using a CORE/TEMPLATECHARS.TXT file.  This file can have any number of entries of the form  VALID &amp;quot;X&amp;quot; Where X can be any valid ascii character.  The string following VALID must b...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== CSV Validation ==&lt;br /&gt;
&lt;br /&gt;
Validation of CSV entries is as follows:&lt;br /&gt;
&lt;br /&gt;
* For integer entries&lt;br /&gt;
Only&lt;br /&gt;
 [0,9]&lt;br /&gt;
 -    (minus character)&lt;br /&gt;
are allowed.&lt;br /&gt;
&lt;br /&gt;
* For string and define entries&lt;br /&gt;
By default only&lt;br /&gt;
 [0,9]&lt;br /&gt;
 [a,z]&lt;br /&gt;
 [A,Z]&lt;br /&gt;
 $    (dollar sign)&lt;br /&gt;
 _    (underscore)&lt;br /&gt;
 .    (period)&lt;br /&gt;
are allowed.  But you can expand this using a CORE/TEMPLATECHARS.TXT file.  This file can have any number of entries of the form&lt;br /&gt;
 VALID &amp;quot;X&amp;quot;&lt;br /&gt;
Where X can be any valid ascii character.  The string following VALID must be exactly 3 chars long and surrounded by speech marks (&amp;quot;).&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=590</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=590"/>
		<updated>2026-01-12T19:32:06Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Empires Modding]]&lt;br /&gt;
* [[Empires Scripting]]&lt;br /&gt;
* [[Empires Callbacks]]&lt;br /&gt;
* [[Empires BattleBoard]]&lt;br /&gt;
* [[Empires Terrain]]&lt;br /&gt;
* [[Empires Hotkeys]]&lt;br /&gt;
* [[CSV Validation]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=589</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=589"/>
		<updated>2025-11-27T21:03:55Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= New functionality for 3DObject =&lt;br /&gt;
See UI docs here: [[UI#3DOBJECT|3DObject]]&lt;br /&gt;
&lt;br /&gt;
= new tabstop tag for string rendering =&lt;br /&gt;
See here [[UI#Strings|Strings]]&lt;br /&gt;
&lt;br /&gt;
= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=588</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=588"/>
		<updated>2025-11-27T21:01:07Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* 3D Object */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based (from VALUE0). Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 3DOBJECT ====&lt;br /&gt;
&lt;br /&gt;
A generic 3D object that is rendered to the center of the screen.  It can have an animation file in the standard format.&lt;br /&gt;
This is picked on only the mesh, so the defined bounds in the UI file are ignored.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
TEXPATH &amp;lt;path&amp;gt; - set the path that textures should be loaded from&lt;br /&gt;
ANIM &amp;lt;animName&amp;gt; - set a start anim for the object to play&lt;br /&gt;
LOOPANIM - loop the animation&lt;br /&gt;
SCALE - additional scale applied to the object on rendering&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Command that can be used:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
SetUIObject3DAnim&lt;br /&gt;
SetUIObject3DShaderValues&lt;br /&gt;
UIObject3DLoad&lt;br /&gt;
&lt;br /&gt;
// places the name of the last mesh (or submesh) in the object that was picked into a working string (default index 0)&lt;br /&gt;
GetUIObject3DLastPicked(objectName [, stringIndex])&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=587</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=587"/>
		<updated>2025-11-27T20:59:59Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Core Object Types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based (from VALUE0). Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== 3D Object ====&lt;br /&gt;
&lt;br /&gt;
A generic 3D object that is rendered to the center of the screen.  It can have an animation file in the standard format.&lt;br /&gt;
This is picked on only the mesh, so the defined bounds in the UI file are ignored.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
TEXPATH &amp;lt;path&amp;gt; - set the path that textures should be loaded from&lt;br /&gt;
ANIM &amp;lt;animName&amp;gt; - set a start anim for the object to play&lt;br /&gt;
LOOPANIM - loop the animation&lt;br /&gt;
SCALE - additional scale applied to the object on rendering&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Command that can be used:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
SetUIObject3DAnim&lt;br /&gt;
SetUIObject3DShaderValues&lt;br /&gt;
UIObject3DLoad&lt;br /&gt;
&lt;br /&gt;
// places the name of the last mesh (or submesh) in the object that was picked into a working string (default index 0)&lt;br /&gt;
GetUIObject3DLastPicked(objectName [, stringIndex])&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
GetUIObject3DLastPicked&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=586</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=586"/>
		<updated>2025-08-01T19:36:37Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Additional Common Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based (from VALUE0). Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=585</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=585"/>
		<updated>2025-08-01T19:36:13Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Additional Common Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
VALUE&amp;lt;N&amp;gt; &amp;lt;value&amp;gt;        // user defined values, generally fed into the code. Zero based. Current max 8. value can be either decimal, or hex prefixed by 0x (e.g. 0xFFFFFFFF)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=584</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=584"/>
		<updated>2025-07-22T16:27:23Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* BUTTON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESCAPE, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=583</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=583"/>
		<updated>2025-07-15T17:46:59Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* BUTTON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLEDCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=582</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=582"/>
		<updated>2025-07-03T19:56:42Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* BUTTON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
DOWNCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
OVERCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
DISABLECOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=581</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=581"/>
		<updated>2025-05-29T20:03:46Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= new tabstop tag for string rendering =&lt;br /&gt;
See here [[UI#Strings|Strings]]&lt;br /&gt;
&lt;br /&gt;
= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=580</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=580"/>
		<updated>2025-05-29T20:02:27Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;tabstopN&amp;gt; moves the rendering to the percent of the width of the output rectangle.  e.g. &amp;lt;tabstop50&amp;gt; is the middle. Undefined behavior for non-single line text. If you are already past the tab point, it moves you back.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=579</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=579"/>
		<updated>2025-05-26T21:10:48Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* LISTBOX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
DROPDOWN - Turn the list into a dropdown menu.  Note that you still define the positioning of the listbox by the listbox size when open. When the dropdown is closed, it shows the selected item at the position where the first item in the open listbox would be.&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=578</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=578"/>
		<updated>2025-05-26T20:53:28Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Custom Keyboard Bindings = &lt;br /&gt;
You enter them in the file CORE/CustomKeys.txt.  Each entry has the form&lt;br /&gt;
 &amp;lt;tag&amp;gt; &amp;lt;key&amp;gt;&lt;br /&gt;
e.g.&lt;br /&gt;
 KK_NEXT_UNSHOT B&lt;br /&gt;
 KK_SOMETHING_ELSE CTRL+Y&lt;br /&gt;
&lt;br /&gt;
Note that the ordering of the modifier keys is different to when used directly on hotkeys (as per the UI docs), apologies for that.&lt;br /&gt;
&lt;br /&gt;
You then use these tags in the UI files for hotkeys, e.g.:&lt;br /&gt;
 …&lt;br /&gt;
 HOTKEY KK_NEXT_UNSHOT&lt;br /&gt;
&lt;br /&gt;
They will appear in the key list and can be rebound etc.&lt;br /&gt;
&lt;br /&gt;
They use the standard string IDs, e.g. &lt;br /&gt;
 IDS_KEYDESC_KK_NEXT_UNSHOT,&amp;quot;Next Unshot&amp;quot;,&lt;br /&gt;
You can use the same tag as a hotkey for multiple UI objects (e.g. if you want a redefinable key for closing dialogs etc).&lt;br /&gt;
&lt;br /&gt;
If there is an object OptionsKeyShowConflict then it will have the string IDS_KEYS_CONFLICTED applied to it if there are key definition conflicts.&lt;br /&gt;
&lt;br /&gt;
If a button called OptionsKeyDefaultButton exists, it will reset the keys to their default&lt;br /&gt;
&lt;br /&gt;
= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=577</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=577"/>
		<updated>2025-03-14T20:49:38Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SFUNCTION script addition =&lt;br /&gt;
You can now define a function using an SFUNCTION tag to allow you to return a string from it.  An example:&lt;br /&gt;
 char gCharArray[64] ;&lt;br /&gt;
 SFUNCTION StringFn()&lt;br /&gt;
 {&lt;br /&gt;
     return gCharArray ;&lt;br /&gt;
 }&lt;br /&gt;
SFUNCTIONs can also be used as normal functions (i.e. ignoring their return values) so you could, for example, have a function that both sets a global string and also returns it, allowing dual use.&lt;br /&gt;
&lt;br /&gt;
= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=576</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=576"/>
		<updated>2025-03-10T16:10:19Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tile: Building Damage =&lt;br /&gt;
There are now two ways to show building damage.&lt;br /&gt;
&lt;br /&gt;
1 - you can do a texture swap by including a _D version of the building texture (that is, have both a MyTexture.dds and a MyTexture_D.dds).&lt;br /&gt;
&lt;br /&gt;
2 - you can use a different model entirely.  This model needs to be named _DAM (so you would have MyModel.s4f and MyModel_DAM.s4f)&lt;br /&gt;
&lt;br /&gt;
You should not use both, as the _D texture is always loaded if it exists, which will waste memory.&lt;br /&gt;
&lt;br /&gt;
= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=575</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=575"/>
		<updated>2025-02-07T17:35:43Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= MaxDebug tweak changes =&lt;br /&gt;
This is now a bitfield&lt;br /&gt;
 1=extra output spew, 2=throw string error popup @ end of loading calls, 4=throw every string error&lt;br /&gt;
Note that the above is the value, not the bit index.  1 keeps the initial behavior.  More bits may be added in future.&lt;br /&gt;
&lt;br /&gt;
= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=574</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=574"/>
		<updated>2024-11-27T18:07:47Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* PROGRESS BAR */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
 WHOLETEXTURE   // boolean that denotes whether the texture is to be shown full sized across the progress bar.&lt;br /&gt;
The WHOLETEXTURE tag means that whichever portion of the progress bar is shown, that will be the proportion of the texture shown.  So any details on (the visible part of) the texture will remain in the same place as the progress value changes.&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=573</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=573"/>
		<updated>2024-11-27T18:05:14Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Progress Bar Textures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESS_BAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=572</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=572"/>
		<updated>2024-11-27T18:04:48Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Progress Bar Textures =&lt;br /&gt;
You can now flag progress bar textures as being 'full sized' - such that they are shown across the full length of the progress bar 'as is' rather than being drawn as a window texture.&lt;br /&gt;
See [[UI#PROGRESSBAR]]&lt;br /&gt;
&lt;br /&gt;
= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=571</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=571"/>
		<updated>2024-11-04T21:58:37Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Achievement Values =&lt;br /&gt;
You can now get and set values for a campaign that are saved in the achievements file.  New script commands&lt;br /&gt;
 SetAchievementValue, 2, 2, &amp;quot;(name, value) set the value of the named achievementvalue.  If doesn't exist will be created.&amp;quot;) &lt;br /&gt;
 GetAchievementValue, 1, 1, &amp;quot;(name) get the value of the named achievementvalue.  If doesn't exist, returns 0.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=570</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=570"/>
		<updated>2024-11-04T18:13:06Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* REGIONMAP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner, selection, and other colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
HIGHLIGHT &amp;lt;highlightcolour&amp;gt;&lt;br /&gt;
// you can have as many of the HIGHLIGHTIGNORE tags as you need, each tells the code to not highlight a given region value&lt;br /&gt;
HIGHLIGHTIGNORE &amp;lt;region&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// this allows you to take the owner details from another channel in the texture. Values are generally 0, 8, 16, or 24.&lt;br /&gt;
OWNERCHANNELSHIFT &amp;lt;shift&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=569</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=569"/>
		<updated>2024-11-04T18:07:37Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Region Map Highlights =&lt;br /&gt;
You can now enable dynamic highlights as the mouse moves over a region map.  See [[UI#REGIONMAP]].&lt;br /&gt;
&lt;br /&gt;
= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=568</id>
		<title>Tools</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=568"/>
		<updated>2024-10-07T21:25:22Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Controls &amp;amp; Key Shortcuts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TOOLS =&lt;br /&gt;
&lt;br /&gt;
== Particle Tool ==&lt;br /&gt;
The particle tool allows for the creation of FXF files.&lt;br /&gt;
&lt;br /&gt;
===Core Concepts===&lt;br /&gt;
The three main elements of the particle system are:&lt;br /&gt;
====Particle Definition====&lt;br /&gt;
This describes individual particles, and how they change over their lifetime.  You can set the lifespan of a particle and how its speed, appearance, etc change.  Particles have a maximum lifespan of 255 ticks (so about 8.5 seconds).  Editing of the particle attributes is done via sliders or curves, depending upon the type of parameter.&lt;br /&gt;
====Emitters====&lt;br /&gt;
And emitter defines which particles are emitted from given points on a model.  The points are identified by an index which is extracted from special naming of model frames (e.g. !3 denotes this frame is emitter index 3).  You can utilise these points by emitting from the position of an emitter frame, along a line between two emitter frames, or you can emiter particles randomly from the surface of the emitter frame (assuming it has a mesh associated with it).  You turn on mesh emission by clicking down the second emitter frame index below zero so it denotes mesh emission.&lt;br /&gt;
====Effects====&lt;br /&gt;
An effect is a set of emitters which can (optionally) be turned on and off during playback via the timings dialog.  The game can trigger effects using the animation and scripting systems.&lt;br /&gt;
&lt;br /&gt;
===Coordinate Types===&lt;br /&gt;
The checkboxes above the particle attribute area control how particles are emitted and move relative to their emitter frame.&lt;br /&gt;
====World====&lt;br /&gt;
If this is checked then the particles with be emitted in world coordinates, irrespective of the orientation of the emitter frame.  So, if a particle is set to travel in the Y direction and this is unchecked, it will emit in the direction of the Y axis of its emitter frame (e.g. if the frame is animated, the direction of emission will change).  If this box is checked then it will emit along the Y axis (so directly up or down) no matter the orientation of the emitter frame.&lt;br /&gt;
====Fixed and Fixed Local====&lt;br /&gt;
Fixed particles will remain with the emitter frame they are associated with.  An example would be a glowing sword.  Setting a stationary particle to fixed would cause it sit on the surface of the sword mesh even as the mesh moved around under animation.  Fixed Local controls how particle movement happens when Fixed is enabled.  When off particles will remain in the frame of reference of their emitter frame.  So in this case, if we change the particles to move in the Y direction then with Fixed Local off the particles would remain in the same positions relative to the sword (so lifting the sword would cause them to move up and stick out like a flag).  Turning in on means that the particles would be positioned along the Y axis relative to their original emission point, no matter the orientation of the sword (e.g. could fall down along the blade and onto the hilt if the sword was raised).&lt;br /&gt;
====FaceEmit====&lt;br /&gt;
Particles are emitted from the center of a random face on the mesh, along the normal of the face.  Cannot be combined with Fixed particles.&lt;br /&gt;
&lt;br /&gt;
===Controls &amp;amp; Key Shortcuts===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A          - toggle animation playback&lt;br /&gt;
F9         - single step animations&lt;br /&gt;
G          - toggle the ground plane display&lt;br /&gt;
F2         - take a screenshot (into a SCREENS subfolder in the EXE folder)&lt;br /&gt;
ENTER      - reset camera position&lt;br /&gt;
I          - toggle info display&lt;br /&gt;
R          - attempt to rotate the _1turret object.  SHIFT+R to cancel&lt;br /&gt;
C          - do a camera reset to show the full object, also removes the info cube&lt;br /&gt;
SPACE      - toggle light between global and camera&lt;br /&gt;
F1         - reload the shaders&lt;br /&gt;
A          - toggle playing of animations&lt;br /&gt;
&lt;br /&gt;
LMB        - hold to rotate camera&lt;br /&gt;
RMB        - hold to move camera target position&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CONFIG.TXT===&lt;br /&gt;
You can set up texture paths for the particles as well as loaded meshes.  This has a similar layout to the config file for the import tool.  Below is an example, obviously using example paths.  Note that all entries (and, indeed, the entire config file) are optional.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// COREPATH points to the path where the CORE folder containing the SHADERS folder is.  Note the trailing slash.&lt;br /&gt;
COREPATH D:\BUILDS\BUILD1\&lt;br /&gt;
// FXPATH points to the folder containing the textures used by the particles&lt;br /&gt;
FXPATH D:\BUILDS\BUILD1\CORE&lt;br /&gt;
&lt;br /&gt;
// if the mesh has an animation file, select this animation to loop on load, if it exists&lt;br /&gt;
DEFAULTANIM &amp;lt;anim name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// define the % of the screen width used by the righthand tool bar (defaults to 12%)&lt;br /&gt;
TOOLBARPERC &amp;lt;percentage&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// background colour&lt;br /&gt;
BACKCOLOUR &amp;lt;colour in hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// the size of the info cube (default is 1)&lt;br /&gt;
CUBESIZE &amp;lt;size as float&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// TEXTURES chunk can contain one or more paths, which are searched in order, for textures to load for any meshes which are loaded into the tool&lt;br /&gt;
[TEXTURES]&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\BATTLE\UNITTEXTURES&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\UI\TEXTURES&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[ detailed docs TBD ]&lt;br /&gt;
&lt;br /&gt;
== The Import Tool ==&lt;br /&gt;
Allows import and conversion from FBX files into the game-specific S4F format.&lt;br /&gt;
&lt;br /&gt;
[[Rendering_and_Shaders#Converter_Tool|Details]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=567</id>
		<title>Tools</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=567"/>
		<updated>2024-10-07T21:22:20Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* CONFIG.TXT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TOOLS =&lt;br /&gt;
&lt;br /&gt;
== Particle Tool ==&lt;br /&gt;
The particle tool allows for the creation of FXF files.&lt;br /&gt;
&lt;br /&gt;
===Core Concepts===&lt;br /&gt;
The three main elements of the particle system are:&lt;br /&gt;
====Particle Definition====&lt;br /&gt;
This describes individual particles, and how they change over their lifetime.  You can set the lifespan of a particle and how its speed, appearance, etc change.  Particles have a maximum lifespan of 255 ticks (so about 8.5 seconds).  Editing of the particle attributes is done via sliders or curves, depending upon the type of parameter.&lt;br /&gt;
====Emitters====&lt;br /&gt;
And emitter defines which particles are emitted from given points on a model.  The points are identified by an index which is extracted from special naming of model frames (e.g. !3 denotes this frame is emitter index 3).  You can utilise these points by emitting from the position of an emitter frame, along a line between two emitter frames, or you can emiter particles randomly from the surface of the emitter frame (assuming it has a mesh associated with it).  You turn on mesh emission by clicking down the second emitter frame index below zero so it denotes mesh emission.&lt;br /&gt;
====Effects====&lt;br /&gt;
An effect is a set of emitters which can (optionally) be turned on and off during playback via the timings dialog.  The game can trigger effects using the animation and scripting systems.&lt;br /&gt;
&lt;br /&gt;
===Coordinate Types===&lt;br /&gt;
The checkboxes above the particle attribute area control how particles are emitted and move relative to their emitter frame.&lt;br /&gt;
====World====&lt;br /&gt;
If this is checked then the particles with be emitted in world coordinates, irrespective of the orientation of the emitter frame.  So, if a particle is set to travel in the Y direction and this is unchecked, it will emit in the direction of the Y axis of its emitter frame (e.g. if the frame is animated, the direction of emission will change).  If this box is checked then it will emit along the Y axis (so directly up or down) no matter the orientation of the emitter frame.&lt;br /&gt;
====Fixed and Fixed Local====&lt;br /&gt;
Fixed particles will remain with the emitter frame they are associated with.  An example would be a glowing sword.  Setting a stationary particle to fixed would cause it sit on the surface of the sword mesh even as the mesh moved around under animation.  Fixed Local controls how particle movement happens when Fixed is enabled.  When off particles will remain in the frame of reference of their emitter frame.  So in this case, if we change the particles to move in the Y direction then with Fixed Local off the particles would remain in the same positions relative to the sword (so lifting the sword would cause them to move up and stick out like a flag).  Turning in on means that the particles would be positioned along the Y axis relative to their original emission point, no matter the orientation of the sword (e.g. could fall down along the blade and onto the hilt if the sword was raised).&lt;br /&gt;
====FaceEmit====&lt;br /&gt;
Particles are emitted from the center of a random face on the mesh, along the normal of the face.  Cannot be combined with Fixed particles.&lt;br /&gt;
&lt;br /&gt;
===Controls &amp;amp; Key Shortcuts===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A          - toggle animation playback&lt;br /&gt;
F9         - single step animations&lt;br /&gt;
G          - toggle the ground plane display&lt;br /&gt;
F2         - take a screenshot (into a SCREENS subfolder in the EXE folder)&lt;br /&gt;
ENTER      - reset camera position&lt;br /&gt;
I          - toggle info display&lt;br /&gt;
&lt;br /&gt;
LMB        - hold to rotate camera&lt;br /&gt;
RMB        - hold to move camera target position&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CONFIG.TXT===&lt;br /&gt;
You can set up texture paths for the particles as well as loaded meshes.  This has a similar layout to the config file for the import tool.  Below is an example, obviously using example paths.  Note that all entries (and, indeed, the entire config file) are optional.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// COREPATH points to the path where the CORE folder containing the SHADERS folder is.  Note the trailing slash.&lt;br /&gt;
COREPATH D:\BUILDS\BUILD1\&lt;br /&gt;
// FXPATH points to the folder containing the textures used by the particles&lt;br /&gt;
FXPATH D:\BUILDS\BUILD1\CORE&lt;br /&gt;
&lt;br /&gt;
// if the mesh has an animation file, select this animation to loop on load, if it exists&lt;br /&gt;
DEFAULTANIM &amp;lt;anim name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// define the % of the screen width used by the righthand tool bar (defaults to 12%)&lt;br /&gt;
TOOLBARPERC &amp;lt;percentage&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// background colour&lt;br /&gt;
BACKCOLOUR &amp;lt;colour in hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// the size of the info cube (default is 1)&lt;br /&gt;
CUBESIZE &amp;lt;size as float&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// TEXTURES chunk can contain one or more paths, which are searched in order, for textures to load for any meshes which are loaded into the tool&lt;br /&gt;
[TEXTURES]&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\BATTLE\UNITTEXTURES&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\UI\TEXTURES&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[ detailed docs TBD ]&lt;br /&gt;
&lt;br /&gt;
== The Import Tool ==&lt;br /&gt;
Allows import and conversion from FBX files into the game-specific S4F format.&lt;br /&gt;
&lt;br /&gt;
[[Rendering_and_Shaders#Converter_Tool|Details]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=566</id>
		<title>Tools</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=566"/>
		<updated>2024-10-07T21:21:40Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* CONFIG.TXT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TOOLS =&lt;br /&gt;
&lt;br /&gt;
== Particle Tool ==&lt;br /&gt;
The particle tool allows for the creation of FXF files.&lt;br /&gt;
&lt;br /&gt;
===Core Concepts===&lt;br /&gt;
The three main elements of the particle system are:&lt;br /&gt;
====Particle Definition====&lt;br /&gt;
This describes individual particles, and how they change over their lifetime.  You can set the lifespan of a particle and how its speed, appearance, etc change.  Particles have a maximum lifespan of 255 ticks (so about 8.5 seconds).  Editing of the particle attributes is done via sliders or curves, depending upon the type of parameter.&lt;br /&gt;
====Emitters====&lt;br /&gt;
And emitter defines which particles are emitted from given points on a model.  The points are identified by an index which is extracted from special naming of model frames (e.g. !3 denotes this frame is emitter index 3).  You can utilise these points by emitting from the position of an emitter frame, along a line between two emitter frames, or you can emiter particles randomly from the surface of the emitter frame (assuming it has a mesh associated with it).  You turn on mesh emission by clicking down the second emitter frame index below zero so it denotes mesh emission.&lt;br /&gt;
====Effects====&lt;br /&gt;
An effect is a set of emitters which can (optionally) be turned on and off during playback via the timings dialog.  The game can trigger effects using the animation and scripting systems.&lt;br /&gt;
&lt;br /&gt;
===Coordinate Types===&lt;br /&gt;
The checkboxes above the particle attribute area control how particles are emitted and move relative to their emitter frame.&lt;br /&gt;
====World====&lt;br /&gt;
If this is checked then the particles with be emitted in world coordinates, irrespective of the orientation of the emitter frame.  So, if a particle is set to travel in the Y direction and this is unchecked, it will emit in the direction of the Y axis of its emitter frame (e.g. if the frame is animated, the direction of emission will change).  If this box is checked then it will emit along the Y axis (so directly up or down) no matter the orientation of the emitter frame.&lt;br /&gt;
====Fixed and Fixed Local====&lt;br /&gt;
Fixed particles will remain with the emitter frame they are associated with.  An example would be a glowing sword.  Setting a stationary particle to fixed would cause it sit on the surface of the sword mesh even as the mesh moved around under animation.  Fixed Local controls how particle movement happens when Fixed is enabled.  When off particles will remain in the frame of reference of their emitter frame.  So in this case, if we change the particles to move in the Y direction then with Fixed Local off the particles would remain in the same positions relative to the sword (so lifting the sword would cause them to move up and stick out like a flag).  Turning in on means that the particles would be positioned along the Y axis relative to their original emission point, no matter the orientation of the sword (e.g. could fall down along the blade and onto the hilt if the sword was raised).&lt;br /&gt;
====FaceEmit====&lt;br /&gt;
Particles are emitted from the center of a random face on the mesh, along the normal of the face.  Cannot be combined with Fixed particles.&lt;br /&gt;
&lt;br /&gt;
===Controls &amp;amp; Key Shortcuts===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A          - toggle animation playback&lt;br /&gt;
F9         - single step animations&lt;br /&gt;
G          - toggle the ground plane display&lt;br /&gt;
F2         - take a screenshot (into a SCREENS subfolder in the EXE folder)&lt;br /&gt;
ENTER      - reset camera position&lt;br /&gt;
I          - toggle info display&lt;br /&gt;
&lt;br /&gt;
LMB        - hold to rotate camera&lt;br /&gt;
RMB        - hold to move camera target position&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CONFIG.TXT===&lt;br /&gt;
You can set up texture paths for the particles as well as loaded meshes.  This has a similar layout to the config file for the import tool.  Below is an example, obviously using example paths.  Note that all entries (and, indeed, the entire config file) are optional.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// COREPATH points to the path where the CORE folder containing the SHADERS folder is.  Note the trailing slash.&lt;br /&gt;
COREPATH D:\BUILDS\BUILD1\&lt;br /&gt;
// FXPATH points to the folder containing the textures used by the particles&lt;br /&gt;
FXPATH D:\BUILDS\BUILD1\CORE&lt;br /&gt;
&lt;br /&gt;
// if the mesh has an animation file, select this animation to loop on load, if it exists&lt;br /&gt;
DEFAULTANIM &amp;lt;anim name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// define the % of the screen width used by the righthand tool bar (defaults to 12%)&lt;br /&gt;
TOOLBARPERC &amp;lt;percentage&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// background colour&lt;br /&gt;
BACKCOLOUR &amp;lt;colour in hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// the size of the info cube (default is 1)&lt;br /&gt;
CUBESIZE &amp;lt;size as float&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// TEXTURES chunk can contain one or more paths, which are searched in order, for textures to load for any meshes which are loaded into the tool&lt;br /&gt;
[TEXTURES]&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\BATTLE\UNITTEXTURES&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\UI\TEXTURES&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[ detailed docs TBD ]&lt;br /&gt;
&lt;br /&gt;
== The Import Tool ==&lt;br /&gt;
Allows import and conversion from FBX files into the game-specific S4F format.&lt;br /&gt;
&lt;br /&gt;
[[Rendering_and_Shaders#Converter_Tool|Details]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=565</id>
		<title>Tools</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=565"/>
		<updated>2024-10-07T21:21:19Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* CONFIG.TXT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TOOLS =&lt;br /&gt;
&lt;br /&gt;
== Particle Tool ==&lt;br /&gt;
The particle tool allows for the creation of FXF files.&lt;br /&gt;
&lt;br /&gt;
===Core Concepts===&lt;br /&gt;
The three main elements of the particle system are:&lt;br /&gt;
====Particle Definition====&lt;br /&gt;
This describes individual particles, and how they change over their lifetime.  You can set the lifespan of a particle and how its speed, appearance, etc change.  Particles have a maximum lifespan of 255 ticks (so about 8.5 seconds).  Editing of the particle attributes is done via sliders or curves, depending upon the type of parameter.&lt;br /&gt;
====Emitters====&lt;br /&gt;
And emitter defines which particles are emitted from given points on a model.  The points are identified by an index which is extracted from special naming of model frames (e.g. !3 denotes this frame is emitter index 3).  You can utilise these points by emitting from the position of an emitter frame, along a line between two emitter frames, or you can emiter particles randomly from the surface of the emitter frame (assuming it has a mesh associated with it).  You turn on mesh emission by clicking down the second emitter frame index below zero so it denotes mesh emission.&lt;br /&gt;
====Effects====&lt;br /&gt;
An effect is a set of emitters which can (optionally) be turned on and off during playback via the timings dialog.  The game can trigger effects using the animation and scripting systems.&lt;br /&gt;
&lt;br /&gt;
===Coordinate Types===&lt;br /&gt;
The checkboxes above the particle attribute area control how particles are emitted and move relative to their emitter frame.&lt;br /&gt;
====World====&lt;br /&gt;
If this is checked then the particles with be emitted in world coordinates, irrespective of the orientation of the emitter frame.  So, if a particle is set to travel in the Y direction and this is unchecked, it will emit in the direction of the Y axis of its emitter frame (e.g. if the frame is animated, the direction of emission will change).  If this box is checked then it will emit along the Y axis (so directly up or down) no matter the orientation of the emitter frame.&lt;br /&gt;
====Fixed and Fixed Local====&lt;br /&gt;
Fixed particles will remain with the emitter frame they are associated with.  An example would be a glowing sword.  Setting a stationary particle to fixed would cause it sit on the surface of the sword mesh even as the mesh moved around under animation.  Fixed Local controls how particle movement happens when Fixed is enabled.  When off particles will remain in the frame of reference of their emitter frame.  So in this case, if we change the particles to move in the Y direction then with Fixed Local off the particles would remain in the same positions relative to the sword (so lifting the sword would cause them to move up and stick out like a flag).  Turning in on means that the particles would be positioned along the Y axis relative to their original emission point, no matter the orientation of the sword (e.g. could fall down along the blade and onto the hilt if the sword was raised).&lt;br /&gt;
====FaceEmit====&lt;br /&gt;
Particles are emitted from the center of a random face on the mesh, along the normal of the face.  Cannot be combined with Fixed particles.&lt;br /&gt;
&lt;br /&gt;
===Controls &amp;amp; Key Shortcuts===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A          - toggle animation playback&lt;br /&gt;
F9         - single step animations&lt;br /&gt;
G          - toggle the ground plane display&lt;br /&gt;
F2         - take a screenshot (into a SCREENS subfolder in the EXE folder)&lt;br /&gt;
ENTER      - reset camera position&lt;br /&gt;
I          - toggle info display&lt;br /&gt;
&lt;br /&gt;
LMB        - hold to rotate camera&lt;br /&gt;
RMB        - hold to move camera target position&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CONFIG.TXT===&lt;br /&gt;
You can set up texture paths for the particles as well as loaded meshes.  This has a similar layout to the config file for the import tool.  Below is an example, obviously using example paths.  Note that all entries (and, indeed, the entire config file) are optional.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
// COREPATH points to the path where the CORE folder containing the SHADERS folder is.  Note the trailing slash.&lt;br /&gt;
COREPATH D:\BUILDS\BUILD1\&lt;br /&gt;
// FXPATH points to the folder containing the textures used by the particles&lt;br /&gt;
FXPATH D:\BUILDS\BUILD1\CORE&lt;br /&gt;
&lt;br /&gt;
// if the mesh has an animation file, select this animation to loop on load, if it exists&lt;br /&gt;
DEFAULTANIM &amp;lt;anim name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// define the % of the screen width used by the righthand tool bar (defaults to 12%)&lt;br /&gt;
TOOLBARPERC &amp;lt;percentage&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// background colour&lt;br /&gt;
BACKCOLOUR &amp;lt;colour in hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// the size of the info cube (default is 1)&lt;br /&gt;
CUBESIZE &amp;lt;size as float&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// TEXTURES chunk can contain one or more paths, which are searched in order, for textures to load for any meshes which are loaded into the tool&lt;br /&gt;
[TEXTURES]&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\BATTLE\UNITTEXTURES&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\UI\TEXTURES&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[ detailed docs TBD ]&lt;br /&gt;
&lt;br /&gt;
== The Import Tool ==&lt;br /&gt;
Allows import and conversion from FBX files into the game-specific S4F format.&lt;br /&gt;
&lt;br /&gt;
[[Rendering_and_Shaders#Converter_Tool|Details]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=564</id>
		<title>Tools</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Tools&amp;diff=564"/>
		<updated>2024-10-07T21:19:29Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* CONFIG.TXT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TOOLS =&lt;br /&gt;
&lt;br /&gt;
== Particle Tool ==&lt;br /&gt;
The particle tool allows for the creation of FXF files.&lt;br /&gt;
&lt;br /&gt;
===Core Concepts===&lt;br /&gt;
The three main elements of the particle system are:&lt;br /&gt;
====Particle Definition====&lt;br /&gt;
This describes individual particles, and how they change over their lifetime.  You can set the lifespan of a particle and how its speed, appearance, etc change.  Particles have a maximum lifespan of 255 ticks (so about 8.5 seconds).  Editing of the particle attributes is done via sliders or curves, depending upon the type of parameter.&lt;br /&gt;
====Emitters====&lt;br /&gt;
And emitter defines which particles are emitted from given points on a model.  The points are identified by an index which is extracted from special naming of model frames (e.g. !3 denotes this frame is emitter index 3).  You can utilise these points by emitting from the position of an emitter frame, along a line between two emitter frames, or you can emiter particles randomly from the surface of the emitter frame (assuming it has a mesh associated with it).  You turn on mesh emission by clicking down the second emitter frame index below zero so it denotes mesh emission.&lt;br /&gt;
====Effects====&lt;br /&gt;
An effect is a set of emitters which can (optionally) be turned on and off during playback via the timings dialog.  The game can trigger effects using the animation and scripting systems.&lt;br /&gt;
&lt;br /&gt;
===Coordinate Types===&lt;br /&gt;
The checkboxes above the particle attribute area control how particles are emitted and move relative to their emitter frame.&lt;br /&gt;
====World====&lt;br /&gt;
If this is checked then the particles with be emitted in world coordinates, irrespective of the orientation of the emitter frame.  So, if a particle is set to travel in the Y direction and this is unchecked, it will emit in the direction of the Y axis of its emitter frame (e.g. if the frame is animated, the direction of emission will change).  If this box is checked then it will emit along the Y axis (so directly up or down) no matter the orientation of the emitter frame.&lt;br /&gt;
====Fixed and Fixed Local====&lt;br /&gt;
Fixed particles will remain with the emitter frame they are associated with.  An example would be a glowing sword.  Setting a stationary particle to fixed would cause it sit on the surface of the sword mesh even as the mesh moved around under animation.  Fixed Local controls how particle movement happens when Fixed is enabled.  When off particles will remain in the frame of reference of their emitter frame.  So in this case, if we change the particles to move in the Y direction then with Fixed Local off the particles would remain in the same positions relative to the sword (so lifting the sword would cause them to move up and stick out like a flag).  Turning in on means that the particles would be positioned along the Y axis relative to their original emission point, no matter the orientation of the sword (e.g. could fall down along the blade and onto the hilt if the sword was raised).&lt;br /&gt;
====FaceEmit====&lt;br /&gt;
Particles are emitted from the center of a random face on the mesh, along the normal of the face.  Cannot be combined with Fixed particles.&lt;br /&gt;
&lt;br /&gt;
===Controls &amp;amp; Key Shortcuts===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;A          - toggle animation playback&lt;br /&gt;
F9         - single step animations&lt;br /&gt;
G          - toggle the ground plane display&lt;br /&gt;
F2         - take a screenshot (into a SCREENS subfolder in the EXE folder)&lt;br /&gt;
ENTER      - reset camera position&lt;br /&gt;
I          - toggle info display&lt;br /&gt;
&lt;br /&gt;
LMB        - hold to rotate camera&lt;br /&gt;
RMB        - hold to move camera target position&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CONFIG.TXT===&lt;br /&gt;
You can set up texture paths for the particles as well as loaded meshes.  This has a similar layout to the config file for the import tool.  Below is an example, obviously using example paths.  Note that all entries (and, indeed, the entire config file) are optional.&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// COREPATH points to the path where the CORE folder containing the SHADERS folder is.  Note the trailing slash.&lt;br /&gt;
COREPATH D:\BUILDS\BUILD1\&lt;br /&gt;
// FXPATH points to the folder containing the textures used by the particles&lt;br /&gt;
FXPATH D:\BUILDS\BUILD1\CORE&lt;br /&gt;
&lt;br /&gt;
// if the mesh has an animation file, select this animation to loop on load, if it exists&lt;br /&gt;
DEFAULTANIM &amp;lt;anim name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// define the % of the screen width used by the righthand tool bar (defaults to 12%)&lt;br /&gt;
TOOLBARPERC &amp;lt;percentage&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// background colour&lt;br /&gt;
BACKCOLOUR &amp;lt;colour in hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// the size of the info cube (default is 1)&lt;br /&gt;
CUBESIZE &amp;lt;size as float&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// TEXTURES chunk can contain one or more paths, which are searched in order, for textures to load for any meshes which are loaded into the tool&lt;br /&gt;
[TEXTURES]&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\BATTLE\UNITTEXTURES&lt;br /&gt;
PATH D:\BUILDS\BUILD1\DATA\UI\TEXTURES&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[ detailed docs TBD ]&lt;br /&gt;
&lt;br /&gt;
== The Import Tool ==&lt;br /&gt;
Allows import and conversion from FBX files into the game-specific S4F format.&lt;br /&gt;
&lt;br /&gt;
[[Rendering_and_Shaders#Converter_Tool|Details]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=563</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=563"/>
		<updated>2024-07-08T22:25:43Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= String File Naming =&lt;br /&gt;
You can now name string files with additional descriptive information.  The filenames must be of the form:&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;.TXT&lt;br /&gt;
Or&lt;br /&gt;
 Text&amp;lt;number&amp;gt;&amp;lt;string&amp;gt;_&amp;lt;tag&amp;gt;.TXT&lt;br /&gt;
Where tag is the standard 3 character language tag.  Note that the string entries do not need to be the same for all the members of a given text file group.  E.g. the follow would be valid&lt;br /&gt;
 Text2General.txt&lt;br /&gt;
 Text2_FRE.txt&lt;br /&gt;
 Text2German_GER.txt&lt;br /&gt;
Restrictions are: you cannot start the description string with a number (can lead to ambiguous filenames).  You cannot duplicate the _??? pattern at the end of a non-localised text filename.&lt;br /&gt;
&lt;br /&gt;
= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=562</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=562"/>
		<updated>2024-05-21T20:37:58Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Stricter String File Checking =&lt;br /&gt;
There is now stricter string checking to determine that lines are either of the form&lt;br /&gt;
 TAG,&amp;quot;string&amp;quot;,&lt;br /&gt;
or&lt;br /&gt;
 // comment&lt;br /&gt;
By default these check failures are shown as warnings, but you can enable error throwing by using the line&lt;br /&gt;
 MAXDEBUG 2&lt;br /&gt;
in the USER.TXT file.  Note that comments can still follow a correctly formatted string line.&lt;br /&gt;
&lt;br /&gt;
= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=561</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=561"/>
		<updated>2024-04-09T15:38:25Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Additional Common Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner and selection colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=560</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=560"/>
		<updated>2024-04-09T15:37:48Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Additional Common Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
KEEPONSCREEN &amp;lt;flags&amp;gt;    // keep the object onscreen.  Values for flags are 1 (ignore vertical), 2 (ignore horizontal), 4 (do both vertical and horizontal)&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner and selection colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=559</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=559"/>
		<updated>2024-03-19T16:50:15Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= ELO Reroll Allows =&lt;br /&gt;
If there is a checkbox named LobbyAllowRerolls in the MP challenge setup screen, then an allow rerolls bool will be set in the misc data.  This is passed into the MP lobby tooltip callbacks as an ALLOWREROLLS param.&lt;br /&gt;
&lt;br /&gt;
There is a new callback in battle RESIGN_BATTLE_CALLBACK.  This should return -1 to do nothing.  If it returns 1, then the skip rating flag will be set when sending the turn.  To facilitate this, there are new script commands:&lt;br /&gt;
 GameAllowsRerolls&lt;br /&gt;
 IsRanked&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=558</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=558"/>
		<updated>2024-02-05T22:36:59Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner and selection colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff|0xff00ff&amp;gt;colour (red with a border colour)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=557</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=557"/>
		<updated>2024-01-29T19:07:32Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* UI and Font Scaling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner and selection colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
&lt;br /&gt;
You can also set the scaling for a specific screen with ALLOWSCALINGCUSTOM &amp;lt;N&amp;gt; where N is the scaling value.  e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ALLOWSCALINGCUSTOM 1300&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.  This will ignore this object and all its children.&lt;br /&gt;
&lt;br /&gt;
If you have elements which are detached from the main UI structure, you can tag their base object with SCALINGPANEL.  This will ignore the object and its children when dealing with screen edges, AND also do a screen edge test on the base object and children, separately.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=556</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=556"/>
		<updated>2024-01-23T21:07:12Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= UI and Font Scaling =&lt;br /&gt;
See: [[UI#UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=555</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=555"/>
		<updated>2024-01-23T21:04:37Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= UI and Font Scaling =&lt;br /&gt;
See: [[UI:UI_and_Font_Scaling]]&lt;br /&gt;
&lt;br /&gt;
= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=554</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=554"/>
		<updated>2024-01-23T21:02:10Z</updated>

		<summary type="html">&lt;p&gt;Phil: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
UI Screens are defined in text files which define the objects and actions of UI screens.  They are made up for 2 main sections, animations and objects.  Animations are defined first in the file, followed by objects.  Animations are not required for the correct operation of most UI screens.&lt;br /&gt;
&lt;br /&gt;
You can include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
You can also add a prefix to an include line.  The prefix is applied to all chunk strings in the file, as well as all PARENT entries.  So an include of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot; Prefix&lt;br /&gt;
would cause all the chunks in the include file to be parsed as &lt;br /&gt;
 [PrefixChunkName]&lt;br /&gt;
and any PARENT entries as&lt;br /&gt;
 PARENT PrefixParentName&lt;br /&gt;
This allows for reuse of UI controls in multiple screens (with some careful naming).&lt;br /&gt;
&lt;br /&gt;
Include files must be in the same folder as the UI file (in which case you should &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; use a .txt extension unless you are sure the system will not try and load the include file as a normal UI file (as would happen in CORE/UI or DATA/UI for example) or in DATA/UI/TEMPLATES.  Files are searched for in this order. Also, you cannot next includes, i.e. included files cannot have #include statements in them.&lt;br /&gt;
&lt;br /&gt;
== Objects ==&lt;br /&gt;
All objects are defined by a minimal data chunk of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[&amp;lt;objectName&amp;gt;]&lt;br /&gt;
TYPE &amp;lt;type&amp;gt;&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
WIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
HEIGHT &amp;lt;h&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the different types of UI objects and their capabilities, defined using additional tags in the chunk, are described below.  All x,y and width, height values are assumed to be based on a 1024x768 screen.&lt;br /&gt;
&lt;br /&gt;
== The Parent Object ==&lt;br /&gt;
&lt;br /&gt;
The first object defined in a file is assumed to be the screen parent object.  Any other object in the file without an explicit PARENT definition is assumed to be a child of the screen parent object.&lt;br /&gt;
&lt;br /&gt;
The screen parent object has a number of unique tags which can be set:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
HANDLER &amp;lt;handlerName&amp;gt;   // handler tags hook in to the code and so should be used with caution.&lt;br /&gt;
                        //In most cases you will want to keep handler values as they are already set in existing/equivalent files.&lt;br /&gt;
MODAL                   // if set, this says that the screen is modal and prevents interaction with any screens below it in the display stack.&lt;br /&gt;
LEVEL &amp;lt;level&amp;gt;           // each screen is created at a fixed level in the screen layers.  It is the order in which screens are displayed.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There can be a hierarchy of parent / child objects below the screen parent object indicated by the PARENT tag on the child.  Child objects are drawn in front of their parents and some properties (for example visibility) of a parent will automatically propagate to their children.  When two sibling objects overlap visually, the object appearing first in the layout is drawn in front.&lt;br /&gt;
&lt;br /&gt;
== Additional Common Tags ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
DRAGGABLE &amp;lt;size&amp;gt;        // denotes that an object is draggable.  Size is the height of draggable top border.&lt;br /&gt;
FOCUS                   // can this object have focus (be moused over, clicked on, etc).  Some objects (e.g. buttons) are always focus-able.&lt;br /&gt;
SFXFOCUS &amp;lt;id&amp;gt;           // play the sound (based on the position in the sound list) when the object is moused over.&lt;br /&gt;
TOOLTIP &amp;lt;stringID&amp;gt;&lt;br /&gt;
ALWAYSTOOL              // always display the tooltip text at the bottom of the object&lt;br /&gt;
ALWAYSTOOLX &amp;lt;offset&amp;gt;    // x display offset for ALWAYSTOOL display&lt;br /&gt;
ALWAYSTOOLY &amp;lt;offset&amp;gt;    // y display offset for ALWAYSTOOL display&lt;br /&gt;
CLIPPING                // &lt;br /&gt;
DX &amp;lt;x&amp;gt;                  // horizontal position relative to parent (overrides X)&lt;br /&gt;
DY &amp;lt;y&amp;gt;                  // vertical position relative to parent (overrides Y)&lt;br /&gt;
PARENT &amp;lt;parentName&amp;gt;     // see The Parent Object&lt;br /&gt;
ATTACH &amp;lt;tags&amp;gt;           // attach an object to a screen edge, with an optional (unscaled) offset. See below.&lt;br /&gt;
SQUAREASPECT            // see below&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
SQUAREASPECT tells controls to maintain their aspect, along with all their children.  This differs from the KEEPSQUARE logic in that the actual positioning of child objects will retain a constant aspect (rather than just their control dimensions, as with KEEPSQUARE).  Effectively, setting SQUAREASPECT on a control will cause it to be centered around it's usual position, with all its children positions as they would have been in their 1024x768 defined coordinates.  So a popup (for example) will have the same look and layout all screen resolutions, but will scale uniformly to the appropriate size.  Note that while it is possible to turn off SQUAREASPECT on child objects of SQUAREASPECT parents, the results will likely be undesired.&lt;br /&gt;
&lt;br /&gt;
Attach takes a single composited string using LRTB for the left, right, top, and bottom screen edges respectively.  An optional offset can be included.  E.g.&lt;br /&gt;
 ATTACH RB        // attach to the bottom right of the screen&lt;br /&gt;
 ATTACH R20B10    // attach to the bottom right, with a 20 pixel offset from the right, and 10 up from the bottom.&lt;br /&gt;
&lt;br /&gt;
== Object Types ==&lt;br /&gt;
=== Map Display [DEPRECATED] ===&lt;br /&gt;
&amp;lt;b&amp;gt;This UI object is currently not supported&amp;lt;/b&amp;gt;&lt;br /&gt;
The Map Display control allows the use of 3D heightmapped maps which can be scrolled and broken into territories.  For details see the detailed documentation.&lt;br /&gt;
[[MapDisplayUIControl|Map Display Documentation]]&lt;br /&gt;
&lt;br /&gt;
=== Core Object Types ===&lt;br /&gt;
==== OBJECT ====&lt;br /&gt;
This is a generic UI object. It is neither visible nor interactable.&lt;br /&gt;
&lt;br /&gt;
==== IMAGE ====&lt;br /&gt;
An image object is simply a displayed texture. Valid tags are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;            // the filename of the texture. The root path is DATA\UI\TEXTURES.&lt;br /&gt;
&lt;br /&gt;
You can show just a portion of a texture by using the additional tags below:&lt;br /&gt;
&lt;br /&gt;
IMAGELEFT &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGETOP &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
IMAGEHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These values are in pixels, so if the texture is resized, they will need to be re-evaluated.&lt;br /&gt;
&lt;br /&gt;
ANIMSPEED &amp;lt;speed&amp;gt;&lt;br /&gt;
ANIMFADE &amp;lt;value&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;        // anywhere colours are specified, they may either be ARGB hex values (ex. ffff0000) or named colours specified in the COLOURDICTIONARY chunk of DATA/UISETTINGS.TXT&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt;       // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 0&lt;br /&gt;
BACKDROP               // when the screen aspect ratio is below 21:9, the texture will be cropped horizontally (ie if a 21:9 background texture is displayed in a 1024 by 768 IMAGE object with BACKDROP, it will fill the screen and&lt;br /&gt;
                       // maintain the correct aspect ratio at all screen ratios up to 21:9, with the left and right edges of the image removed as required)&lt;br /&gt;
MODULATE              // use a modulate blend when rendering, multiplying (darkening) the screen based on the source image colours&lt;br /&gt;
SLICED &amp;lt;pixels&amp;gt; &amp;lt;size&amp;gt; // use a 9-sliced setup for the image. pixels is the size in pixels of a corner slice in the texture. size is the 1024-space size of a corner in the UI Image onscreen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== DISPLAY ====&lt;br /&gt;
&lt;br /&gt;
A display object is a non interactive display. It draws a simple window using a window template texture.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;        // texture filename&lt;br /&gt;
&lt;br /&gt;
The window template is laid as as follows (generally it is assumed the texture will be 256x256). The corner 1/16ths of the texture are the corners of the window - these are drawn at 64x64. The top and bottom and left and right center halves are the frames (these are stretched to size) and then the middle of the texture is stretch to cover the remaining center of the window.&lt;br /&gt;
&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Used to display a window title when used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BUTTON ====&lt;br /&gt;
&lt;br /&gt;
Button objects are displayed using a texture file. This file must contain 4 versions of the button. These are arranged as follows:&lt;br /&gt;
&lt;br /&gt;
* Normal  - top left&lt;br /&gt;
* Moused Over  - top right&lt;br /&gt;
* Pressed  - bottom left&lt;br /&gt;
* Inactive (greyed)  - bottom right&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;    // texture name&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
IMAGEU &amp;lt;u&amp;gt;&lt;br /&gt;
IMAGEV &amp;lt;v&amp;gt;&lt;br /&gt;
GROUP &amp;lt;group&amp;gt; // the number of the group this button belongs to (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
GROUPINDEX &amp;lt;groupIndex&amp;gt; // the index within a group for this button (for use with Get/SetUIGroupSelection commands)&lt;br /&gt;
SIMPLEIMAGE &amp;lt;0/1&amp;gt; // treat the FILE as a single image rather than the 4 images described above&lt;br /&gt;
TEXTLEFT &amp;lt;x&amp;gt; // placement values for the text within the button (absolute if object is placed absolutely, relative to self if object is placed relatively)&lt;br /&gt;
TEXTTOP &amp;lt;y&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;w&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;h&amp;gt;&lt;br /&gt;
KEEPSQUARE &amp;lt;0/1&amp;gt; // keep the object aspect ratio from the layout when scaling to non 4:3 resolutions, default 1&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; // allow wrapped, multiline text on the button, default 0&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; // horizontally center text on the button, default 1&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; // vertically center text on the button, default 1&lt;br /&gt;
HOTKEY &amp;lt;key&amp;gt; // define a key which will also trigger the button. See below for more details.&lt;br /&gt;
CHECKBOX &amp;lt;0,1&amp;gt; // render this button as a checkbox.  Should be paired with CHECKBOXTICK&lt;br /&gt;
CHECKBOXTICK &amp;lt;filename&amp;gt; // the name of the image containing the tick used when drawing a checkbox-style button&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; // if text is too long for button, scroll horizontally over time (cannot be used with MULTILINE)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
For hotkeys, valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12.  You can also add required modifiers using +SHIFT and/or +CTRL.  If using both must be +SHIFT+CTRL.  No whitespace allowed in definition.  You can automatically show hotkey definitions as tooltips (added in a new line after any defined tooltip).  To enable this either add&lt;br /&gt;
 SHOWHOTKEYS 1&lt;br /&gt;
To the UI settings file for the given flavour, or you can add SHOWHOTKEY to the specific object definition in its UI file.  When showing these tooltip additions you can define a number of strings, all are optional:&lt;br /&gt;
 IDS_SYS_SHIFT_KEY,&amp;quot;string for SHIFT&amp;quot;,&lt;br /&gt;
 IDS_SYS_CONTROL_KEY,&amp;quot;string for CTRL&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY,&amp;quot;Prefix for the hotkey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_SHOW_HOTKEY_POST,&amp;quot;postfix for the hokey string&amp;quot;,&lt;br /&gt;
 IDS_SYS_KEY_&amp;lt;key code&amp;gt;,&amp;quot;string for a given key&amp;quot;&lt;br /&gt;
As an example you would use IDS_SYS_KEY_A for the A key, or IDS_SYS_KEY_RETURN for the return/enter key.  The end tag must match the tag used in the hotkey definition.&lt;br /&gt;
&lt;br /&gt;
==== TEXT ====&lt;br /&gt;
&lt;br /&gt;
A static text object used to display information to the user.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
STRING &amp;lt;stringID&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
BORDER &amp;lt;colour&amp;gt;&lt;br /&gt;
CENTER        // Causes the text to be centered horizontally in the rectangle.&lt;br /&gt;
VCENTER       // causes the text to be vertically centered in the rectangle&lt;br /&gt;
WINDOWEDBACK&lt;br /&gt;
RESCALE&lt;br /&gt;
RESCALEMAX &amp;lt;value&amp;gt; // Sets the maximum height for RESCALE. If used in conjunction with SCROLLING, the text object will start to Scroll when it reaches the set maximum height.&lt;br /&gt;
RESCALELOCK &amp;lt;byte value&amp;gt;  // lock growth direction for RESCALE. 0 centered (default), 1 grow down, 2 grow up.&lt;br /&gt;
FILE &amp;lt;filename&amp;gt;&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list within the main object window.&lt;br /&gt;
SCROLLING &amp;lt;filename&amp;gt; // adds a scrollbar to the text of needed, filename is the name for the scrolling control texture (equivalent to CONTROLTEX on a LISTBOX)&lt;br /&gt;
BARSIZE &amp;lt;size&amp;gt; // this size of the scrollbar is a SCROLLING control texture is specified (default 16)&lt;br /&gt;
SCROLLBOUNCE &amp;lt;0/1&amp;gt; // bounce when scrolling to the limit of the text (default 1)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== LISTBOX ====&lt;br /&gt;
&lt;br /&gt;
A listbox allowing the user to scroll through and select lines. &lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
CONTROLTEX &amp;lt;filename&amp;gt;&lt;br /&gt;
Required, contains all the various listbox controls. The texture is laid out as follows:&lt;br /&gt;
Up scroll arrow - top left&lt;br /&gt;
Down scroll arrow - top right&lt;br /&gt;
Scrollbar  - bottom left (this is stretched to the height of the listbox)&lt;br /&gt;
Scroll nub  - bottom right&lt;br /&gt;
&lt;br /&gt;
FRAMETEX &amp;lt;filename&amp;gt; - used for the listbox frame&lt;br /&gt;
SELTEX &amp;lt;filename&amp;gt; - selection display, this is stretched across the width of the selection box&lt;br /&gt;
BUTTONTEX &amp;lt;filename&amp;gt; - applied to element in the listbox, texture layout is the same as a BUTTON type&lt;br /&gt;
&lt;br /&gt;
TEXTLEFT &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTTOP &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTWIDTH &amp;lt;value&amp;gt;&lt;br /&gt;
TEXTHEIGHT &amp;lt;value&amp;gt;&lt;br /&gt;
Screen placement values for the actual text list, absolute if list is placed absolutely, relative to list if object is placed relatively&lt;br /&gt;
&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt; - the font of the listbox item text&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt; - the colour of the listbox item text.&lt;br /&gt;
BARSIZE &amp;lt;value&amp;gt; - Sets the size of the scrollbar. Default value is 1/3 the horizontal resolution of the CONTROLTEX texture. -ve value causes it to scale with any SQUAREASPECT scaling on the listbox&lt;br /&gt;
ITEMSPACING &amp;lt;value&amp;gt; - spacing between listbox items (vertical or horizontal depending on type of listbox), default value is 0&lt;br /&gt;
ITEMSIZE &amp;lt;value&amp;gt; - the size of the listbox items (vertical or horizontal depending on type of listbox), default is the height of one line of text for vertical listboxes and the max width to fit all items for horizontal listboxes&lt;br /&gt;
ITEMKEEPSQUARE - causes the scaling of ITEMSPACING and ITEMSIZE to maintain the item layout aspect ratio at non-4:3 resolutions&lt;br /&gt;
HORIZONTAL - causes the items to be displayed horizontally across the listbox, only the arrow elements of CONTROLTEX are used (and rotated) for left/right scrolling&lt;br /&gt;
MULTISELECT - allows multiselection in list with standard Ctrl and Shift click modifiers, use IsUIListboxItemSelected to test selections&lt;br /&gt;
AUTOSCROLL - scroll to the bottom of the list when new items are added&lt;br /&gt;
MAXSCROLL &amp;lt;value&amp;gt; - limit on the number of lines scrolled by the mouse wheel&lt;br /&gt;
TEXTMODE - mode for showing multiline text entries&lt;br /&gt;
&lt;br /&gt;
MULTILINE &amp;lt;0/1&amp;gt; - allow wrapped, multiline text in listbox items, default 0 (note, this is different than a TEXTMODE listbox, &lt;br /&gt;
                  you will likely need to adjust ITEMSIZE to actually make room to display multiple lines in a single item)&lt;br /&gt;
CENTER &amp;lt;0/1&amp;gt; - horizontally center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
VCENTER &amp;lt;0/1&amp;gt; - vertically center text on listbox items, default 0 unless a BUTTONTEX is also given&lt;br /&gt;
AUTOTOOLTIP &amp;lt;0/1&amp;gt; - if an item is too wide to display in the listbox using standard drawing and no tooltip is given, &lt;br /&gt;
                    automatically show the item string as the tooltip&lt;br /&gt;
TABLE &amp;lt;headerID&amp;gt; - Draw the listbox as a table with a header and aligned columns. Item strings (and optionally, their tooltips) and the &lt;br /&gt;
                   string referenced by headerID are treated as tab (\t) delimited rows. Behaviour may also be activated or updated &lt;br /&gt;
                   using the SetUIListboxTable command.&lt;br /&gt;
LISTALIGN &amp;lt;alignment&amp;gt; - when there are not enough items to fill the visible listbox, align the items to the &amp;quot;CENTER&amp;quot; or &amp;quot;BOTTOM&amp;quot; (or &lt;br /&gt;
                        &amp;quot;RIGHT&amp;quot;) of the listbox&lt;br /&gt;
MARQUEE &amp;lt;0,1&amp;gt; - if text is too long for item, scroll horizontally over time (cannot be used with MULTILINE)&lt;br /&gt;
TEXTINSET &amp;lt;value&amp;gt; - inset the item text horizontally by a given value (in addition to restrictions set by TEXTLEFT, TEXTWIDTH)&lt;br /&gt;
COLUMNS &amp;lt;value&amp;gt; - use more than one column in the list box.  The items are displayed left to right then top to bottom.  Does not work for horizontal listboxes.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also define a custom item rendering callback&lt;br /&gt;
 FUNCTION UI_OBJ_RENDER_ITEM(x,y,width,height,pass,flags, item, name)&lt;br /&gt;
which operates for each listbox item. The flags param has bits set for selection (bit 0) and mouseover (bit 1), item is the index of the item in the listbox, name is the UI object name, pass is zero prior to default rendering, and 1 after.  Returning non-zero will prevent default item rendering.&lt;br /&gt;
&lt;br /&gt;
In the case of wanting to block a list box selection event use&lt;br /&gt;
 FUNCTION UI_LISTBOX_SELECTION_VALIDATE(data, event, id, name)&lt;br /&gt;
If the function returns 0 the select event will not be passed. Good for disabled buttons and states which shouldn't be selected with custom rendering.&lt;br /&gt;
&lt;br /&gt;
==== EDITBOX ====&lt;br /&gt;
&lt;br /&gt;
A single line text entry box.&lt;br /&gt;
&lt;br /&gt;
Valid tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
MAXCHARS &amp;lt;count&amp;gt;&lt;br /&gt;
CURSORCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PROGRESS BAR ====&lt;br /&gt;
Progress bar and slider control.  Note the common COLOUR tag changes the bar colour, not the text (which has its own tag as below).&lt;br /&gt;
 &lt;br /&gt;
 BARTEXTURE &amp;lt;filename&amp;gt; // required&lt;br /&gt;
 BARLEFT &amp;lt;xcoord&amp;gt;&lt;br /&gt;
 BARTOP &amp;lt;ycoord&amp;gt;&lt;br /&gt;
 BARWIDTH &amp;lt;width&amp;gt;&lt;br /&gt;
 BARHEIGHT &amp;lt;height&amp;gt;&lt;br /&gt;
 TEXTCOLOUR &amp;lt;colour&amp;gt;&lt;br /&gt;
 NUB &amp;lt;nub image file&amp;gt;&lt;br /&gt;
 NUBWIDTH &amp;lt;width&amp;gt;  // defaults to 32&lt;br /&gt;
&lt;br /&gt;
==== REGIONMAP ====&lt;br /&gt;
&lt;br /&gt;
A specialist control for representing a map of distinct regions.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The texture for the region map must be crafted in a specific way.  It should be a 4 channel TGA file.&lt;br /&gt;
The channels in the file are used in the following way:&lt;br /&gt;
&lt;br /&gt;
R - a monochrome image layer.  A region is coloured with its owning sides colour modulated with this channel.&lt;br /&gt;
G - selected layer.  The currently selected region has this layer coloured with the defined selection colour and &lt;br /&gt;
blended with the normal map pixels.&lt;br /&gt;
B - currently unused&lt;br /&gt;
A - region layer.  The alpha value of each pixel denotes which region the pixel belongs to.  &lt;br /&gt;
Value 255 is a special value for invalid pixels which belong to no region.&lt;br /&gt;
&lt;br /&gt;
You can also provide a .DAT file (with the same name as the texture file) to define the owner and selection colours.  These are of the format:&lt;br /&gt;
&lt;br /&gt;
SELECT &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL0 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
COL1 &amp;lt;hexcolour&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
SELECT FFFF00&lt;br /&gt;
COL0 FFFFFF&lt;br /&gt;
COL1 FF00FF&lt;br /&gt;
&lt;br /&gt;
Enhanced Graphics&lt;br /&gt;
You can also provide enhanced graphical files if you desire.  There are two ways of doing this, which all interoperate correctly.&lt;br /&gt;
&lt;br /&gt;
You can provide a single drawn image by using the tag in the global chunk&lt;br /&gt;
&lt;br /&gt;
HANDDRAWN &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This image is used in place of the monochrome channel from the main texture file.  The alpha channel determines how the side&lt;br /&gt;
colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, &lt;br /&gt;
and other values blending the modulated colour with the original image.&lt;br /&gt;
&lt;br /&gt;
You can also provide pre-created images for each side.  That is, when a side owns an area then if an image for that side &lt;br /&gt;
exists, the system will display that section of the drawn image with no colouration or other changes.  These are &lt;br /&gt;
defined by the tag in the global chunk &lt;br /&gt;
&lt;br /&gt;
DRAWN&amp;lt;N&amp;gt; &amp;lt;texture&amp;gt;&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
DRAWN0 side0.tga&lt;br /&gt;
&lt;br /&gt;
sets the texture to be shown when an area is owned by side zero.&lt;br /&gt;
&lt;br /&gt;
Per-Area Data&lt;br /&gt;
You can also set up data for each area in their own chunk.  Valid tags are:&lt;br /&gt;
&lt;br /&gt;
X &amp;lt;x&amp;gt;&lt;br /&gt;
Y &amp;lt;y&amp;gt;&lt;br /&gt;
DATA &amp;lt;a&amp;gt; [&amp;lt;b&amp;gt; &amp;lt;c&amp;gt; &amp;lt;d&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Where X and Y are the region map image pixel coordinates of the center point of the area (retrieved in script as 1024x768 &lt;br /&gt;
coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.&lt;br /&gt;
There can be up to 4 data elements in the list.&lt;br /&gt;
&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that &lt;br /&gt;
this region data is NOT saved as part of a save game and so the Set function should only be used for data which &lt;br /&gt;
can be rebuilt when the screen is activated etc. &lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[44]        // chunk header should contain the index of the area&lt;br /&gt;
X 100&lt;br /&gt;
Y 300&lt;br /&gt;
DATA 100 4 5        // unset data is initialised to zero&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== VARIABLEEDIT ====&lt;br /&gt;
&lt;br /&gt;
This is a control specially built to enable quick and simple editing of data stored in a script structure.  The UI file itself only contains the basic positioning details of the control, with scripting being used to set up the structure type to be edited and any custom layout functionality.&lt;br /&gt;
&lt;br /&gt;
The default behaviour is to list all the structure elements arranged to fill the control area, or centered horizontally if all elements will fit.  The logic attempts to ensure the same layout irrespective of resolution.&lt;br /&gt;
&lt;br /&gt;
Valid Tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands used to set up and control a VariableEdit control are&lt;br /&gt;
&lt;br /&gt;
//set up a variable edit control with the structure you want to edit. The customFilename points to a file which allows setup of custom entry positioning/fonts and other details.&lt;br /&gt;
VariableEditSetStruct(objectName, structName, [customFilename])&lt;br /&gt;
&lt;br /&gt;
//fill the edit control with the values from the given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditSetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
//use the edit control to set the values of a given variable.  Requires the variable name string, not the variable itself.&lt;br /&gt;
VariableEditGetVariable(objectName, variableName)&lt;br /&gt;
&lt;br /&gt;
The custom layout file has a syntax as below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;elementName&amp;gt; I&lt;br /&gt;
&amp;lt;elementName&amp;gt; R &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;width&amp;gt; &amp;lt;height&amp;gt; [&amp;lt;editbox width&amp;gt;]&lt;br /&gt;
&amp;lt;elementName&amp;gt; C &amp;lt;hexColour&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; F &amp;lt;fontname&amp;gt;&lt;br /&gt;
&amp;lt;elementName&amp;gt; B&amp;lt;sizePercent&amp;gt;:&amp;lt;buttonTextureName&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The elementName can be either an explicit name, a wildcard string name, or apply to all members of an array, as follows&lt;br /&gt;
&lt;br /&gt;
type I		// ignore the type element of the structure&lt;br /&gt;
type* I		// ignore the type element and any other elements which start with type&lt;br /&gt;
type? I		// ignore all array entries for the type element&lt;br /&gt;
&lt;br /&gt;
Examples of usage are&lt;br /&gt;
&lt;br /&gt;
type R 10 10 100 40	&lt;br /&gt;
// all in 1024x768 coordinate space&lt;br /&gt;
&lt;br /&gt;
type C FFFF00FF&lt;br /&gt;
// magenta fully opaque&lt;br /&gt;
type F smallFont&lt;br /&gt;
&lt;br /&gt;
type B50:plain_button.tga&lt;br /&gt;
// rather than an edit box, have a button taking up 50% of the width of the area&lt;br /&gt;
&lt;br /&gt;
By default the edit boxes are set up to only accept numeric input.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== TABSET ====&lt;br /&gt;
&lt;br /&gt;
Creates a set of buttons which automatically enable or disable other objects in the screen based on which is currently active.&lt;br /&gt;
&lt;br /&gt;
Valid tags&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FONT &amp;lt;fontname&amp;gt;&lt;br /&gt;
COLOUR &amp;lt;hex colour&amp;gt;&lt;br /&gt;
MAXWIDTH &amp;lt;maximum button width&amp;gt;&lt;br /&gt;
FILE &amp;lt;button texture filename&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The control creates a button for each of its direct child objects.  The button order is the reverse of the order the objects are defined in the UI file.&lt;br /&gt;
&lt;br /&gt;
The text on the buttons defaults to the name of the UI object, but you can add a text file entry of the form&lt;br /&gt;
&lt;br /&gt;
TAB_&amp;lt;objectname&amp;gt; &lt;br /&gt;
&lt;br /&gt;
and this will be used.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3DVIEW ====&lt;br /&gt;
&lt;br /&gt;
Creates a 3D viewport into which you can load 3D models for viewing.  The COLOUR tag for this control sets the background clear colour (use zero for a transparent background, FF000000 for black).&lt;br /&gt;
&lt;br /&gt;
Script commands to control this are:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//if filename starts with # then defaults to standard unit loading paths.&lt;br /&gt;
UIObject3DLoad(objectName, filename, [texturePath])&lt;br /&gt;
&lt;br /&gt;
//automatically set the zoom and camera origin to the size of the currently loaded object&lt;br /&gt;
UIObject3DAuto(objectName)&lt;br /&gt;
&lt;br /&gt;
//set the origin position and vertical angle of the camera.  Optionally change the zoom. xyz are in 100ths&lt;br /&gt;
SetUIObject3DCamera(objectName, x,y,z,angle,[zoom])&lt;br /&gt;
&lt;br /&gt;
//set the options for the view.  0 for off, nonzero for on.&lt;br /&gt;
SetUIObject3DOptions(objectName, allowZoom, allowHorizontalRotate, allowVerticalRotate)&lt;br /&gt;
&lt;br /&gt;
//set the rotation angle for the 3D view&lt;br /&gt;
SetUIObject3DRotation(objectName, angle)&lt;br /&gt;
&lt;br /&gt;
//set the zoom for the given 3D view&lt;br /&gt;
SetUIObject3DZoom(objectName, zoom)&lt;br /&gt;
&lt;br /&gt;
//play an animation, which must be set up in the standard text file. If index then it will play a specific anim (if it exists) otherwise random. Loops if loop is != 0, defaults on&lt;br /&gt;
SetUIObject3DAnim(objectName, animName, [loop, index])&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BARCHART ====&lt;br /&gt;
&lt;br /&gt;
A vertical bar graph.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
BARTEX &amp;lt;filename&amp;gt; - texture for the bars of the graph (optional, otherwise will be drawn in a solid colour)&lt;br /&gt;
TILED &amp;lt;0/1&amp;gt; - if 1, BARTEX will be tiled vertically on the bars, otherwise it will be stretched (default 0)&lt;br /&gt;
COLOUR - the colour for the text and axis lines&lt;br /&gt;
BORDER - the colour for the text outline and bar outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
HLABEL - the label for the horizontal axis of the graph&lt;br /&gt;
VLABEL - the label for the vertical axis of the graph&lt;br /&gt;
STACKED &amp;lt;0/1&amp;gt; - if 1, multiple bars within a category will be drawn stacked vertically, otherwise they will be placed beside each other (default 0)&lt;br /&gt;
MAXBARWIDTH - limit on the width of bars&lt;br /&gt;
COLOUR0 to COLOUR9 - the colours used for bars within a category&lt;br /&gt;
KEY0 to KEY9 - the descriptions of the bars within a category displayed in the key (if there are multiple bars) and tooltip&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data to a BARCHART UI object, multiple values can be given to show multiple bars in a category, category name is taken from UI string 0&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the bar within a category of a BARCHART UI, the text description of the bar is taken from string 0&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//set the title, horizontal label, and vertical label for a chart&lt;br /&gt;
SetUIChartLabels(objectName, titleStringTag, horizLabelStringTag, vertLabelStringTag)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a BARCHART UI by category. direction: 0 ascending (default), 1 descending. numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a BARCHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PIECHART ====&lt;br /&gt;
&lt;br /&gt;
A pie chart.&lt;br /&gt;
&lt;br /&gt;
Tags:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
FILE &amp;lt;filename&amp;gt; - background image, windowed (optional)&lt;br /&gt;
COLOUR - the colour for the text&lt;br /&gt;
BORDER - the colour for the text outline and slice outlines&lt;br /&gt;
STRING - the title of the graph&lt;br /&gt;
COLOUR0 to COLOUR15 - the colours used for slices (more colours can be set from script after data is added)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Special commands:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//add or update data for a PIECHART UI object, category name is taken from UI string 0, returns the index of the slice, &lt;br /&gt;
//optional value# parameters not relevant to pie charts&lt;br /&gt;
SetUIChartData(objectName, value, [valueN], ...)&lt;br /&gt;
&lt;br /&gt;
//set the colour for the slice of a PIECHART UI by index&lt;br /&gt;
SetUIChartColours(objectName, index, colour)&lt;br /&gt;
&lt;br /&gt;
//sort existing data in a PIECHAT UI by category. direction: 0 ascending (default), 1 descending. &lt;br /&gt;
//numeric: 0 sort category names alphabetically (default), 1 treat category names as numbers (ie &amp;quot;2&amp;quot; &amp;lt; &amp;quot;10&amp;quot;)&lt;br /&gt;
SortUIChartData(objectName, [direction], [numeric])&lt;br /&gt;
&lt;br /&gt;
//clear data from a PIECHART UI object&lt;br /&gt;
ClearUIChartData(objectName)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Object Commands ==&lt;br /&gt;
&lt;br /&gt;
All objects can have one or more commands attached to them.  Commands are inbuilt UI commands to allow for simple actions to occur.  While any object can have a command attached to it, not all are able to trigger nor respond to them.&lt;br /&gt;
&lt;br /&gt;
Available commands are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND DISABLE &amp;lt;screen&amp;gt;&lt;br /&gt;
COMMAND PRESS &amp;lt;UIObject&amp;gt;&lt;br /&gt;
COMMAND SHOWBOX &amp;lt;stringID&amp;gt;&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK &amp;lt;url&amp;gt;&lt;br /&gt;
COMMAND CUSTOM &amp;lt;value&amp;gt;            // send a custom value to a code-defined handler in the game&lt;br /&gt;
COMMAND KEY &amp;lt;key&amp;gt;        // simulate a key press.  Can be any alphanumeric key value, or the special TAB value for the tab key. &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for example&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
COMMAND ENABLE MAINMENU&lt;br /&gt;
COMMAND DISABLE POPUP&lt;br /&gt;
COMMAND PRESS POPUPOKBUTTON&lt;br /&gt;
COMMAND SHOWBOX IDS_HELPFUL_MESSAGE&lt;br /&gt;
COMMAND CLOSEGAMEANDOPENLINK someurlonslitherine.html&lt;br /&gt;
COMMAND CUSTOM 55&lt;br /&gt;
COMMAND KEY F &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All commands are checked for validity (that is, that the objects they reference are defined) during UI system loading.  Screens are defined by the name of the root objects defined in them.&lt;br /&gt;
&lt;br /&gt;
Current command triggers are:&lt;br /&gt;
&lt;br /&gt;
* BUTTON - commands triggered on press&lt;br /&gt;
* EDITBOX - commands triggered on RETURN key&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
Animations are defined at the top of a UI file, and their chunks all start with a # symbol as shown below.  An animation with the name #START will be played whenever the screen is activated.  Other named animations can be triggered from scripts etc.  All animation commands work on a tick-based timer which is always reset to zero when an animation is played.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
[#&amp;lt;name&amp;gt;]&lt;br /&gt;
ANIM PLACE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt;&lt;br /&gt;
// place the object at the given coordinates on the given tick&lt;br /&gt;
ANIM MOVE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;x&amp;gt; &amp;lt;y&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// move the object from its current position to a new set of coordinates over a given number of steps&lt;br /&gt;
ANIM SCROLL &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;dx&amp;gt; &amp;lt;dy&amp;gt; &amp;lt;startx&amp;gt; &amp;lt;starty&amp;gt; &amp;lt;endx&amp;gt; &amp;lt;endy&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// move an object from one point to another in steps of dx,dy.  If loop is not zero then it will loop indefinitely.&lt;br /&gt;
ANIM BOUNCE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startScale&amp;gt; &amp;lt;endScale&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// cause the object to 'bounce' scale up in size and then back over time.  The scales are in 1000ths, so to bounce an object without changing its size, you would use 1000 1000.&lt;br /&gt;
ANIM OFF &amp;lt;object&amp;gt;&lt;br /&gt;
// disable an screen via its parent object name.  Only works on top level objects.&lt;br /&gt;
ANIM SFX &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;soundID&amp;gt; [&amp;lt;bank&amp;gt;]&lt;br /&gt;
// play a UI SFX at the given time.  The soundID is the position in the sound list.&lt;br /&gt;
ANIM TIME &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;delta&amp;gt;&lt;br /&gt;
// change the 'time' for a given object.  Each object can have its own flow of time, and this allows (e.g.) a single object on a screen to execute its animations over and over (if delta is &amp;lt;0, moving time back and allowing an object to execute its animations again.&lt;br /&gt;
ANIM FADE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startColour&amp;gt; &amp;lt;endColour&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the colour (including alpha) of an object over time.  Colours should be defined as hex values in AARRGGBB order, e.g. FFFFFFFF for fully opaque white.&lt;br /&gt;
ANIM SCALE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startH&amp;gt; &amp;lt;startV&amp;gt; &amp;lt;endH&amp;gt; &amp;lt;endV&amp;gt; &amp;lt;steps&amp;gt;&lt;br /&gt;
// change the scale of an object over time.&lt;br /&gt;
ANIM ROTATE &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;startRot&amp;gt; &amp;lt;endRot&amp;gt; &amp;lt;steps&amp;gt; &amp;lt;loop&amp;gt;&lt;br /&gt;
// rotate an object over time&lt;br /&gt;
ANIM SHOW &amp;lt;object&amp;gt; &amp;lt;time&amp;gt; &amp;lt;show&amp;gt;&lt;br /&gt;
// set the visiblity of an object. show == 0 will hide the object, otherwise it will be shown &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
To allow for localization, strings displayed in UIs are referenced by IDs corresponding to entries in string files, typically DATA/TEXT/TEXT#.TXT or TEXT#.TXT in the current campaign directory.  Text may also be assigned to UI components at runtime by scripts.&lt;br /&gt;
&lt;br /&gt;
Some formatting of strings is possible using tags embedded in strings, similar to HTML.&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;b&amp;gt;bold&amp;lt;/b&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;i&amp;gt;italics&amp;lt;/i&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;line break: &amp;lt;br&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;h1&amp;gt;heading&amp;lt;/h1&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;colour=0xffffff&amp;gt;colour (red)&amp;lt;/colour&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image: &amp;lt;img=filename.tga&amp;gt;&amp;lt;/nowiki&amp;gt; If you place a # ahead of the filename it will scale the output to match the image's aspect ratio rather than being square&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;tinted inline image: &amp;lt;img=filename.tga colour=0xff0000&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;inline image with backdrop: &amp;lt;img=filename.tga|backdrop.tga&amp;gt;&amp;lt;/nowiki&amp;gt; Note the backdrop is always rendered to the same rect as the main image&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;c&amp;gt;small caps string&amp;lt;/c&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;fN&amp;gt;another font&amp;lt;/f&amp;gt;&amp;lt;/nowiki&amp;gt; The numeric value N is the (base zero) index of the font in the fonts file, e.g. &amp;lt;f12&amp;gt;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;&amp;lt;a&amp;gt;This is horizontally centered&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt; Centers the given line(s) horizontally in the text box.&lt;br /&gt;
* a double quote character in a string file must be escaped with a additional double quote, ex. &amp;quot;Please use the &amp;quot;&amp;quot;Show preview&amp;quot;&amp;quot; button&amp;quot;&lt;br /&gt;
* &amp;lt;nowiki&amp;gt;for line breaks, you may alternatively use a ~ character in the string files or \n in literal strings in script&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can embed clickable links in a string by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;html&amp;gt;http://www.slitherine.com&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;=0023Custom Link&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;http://www.slitherine.com|This is display text&amp;lt;/html&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
for a url link (which will close the game and open the link in a browser if clicked), or a custom link (which will be caught in a UI script with event==1024 and the data parameter containing the 4 digit decimal value following the = sign). Custom strings must always start with =NNNN.  Display strings can be shown rather than the links by using the | seperator, link first followed by the display string.  Note you can add a LINKCOLOUR entry to a text object to change the colour that a link shows as when moused over.&lt;br /&gt;
&lt;br /&gt;
You can have text display in two columns (left column right justified) by using&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:[center]:[gap]:[edge]&amp;gt;[first column text]===[second column text]===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
e.g. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;column:50:10:5&amp;gt;First column===This is text in the second column===&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
The center, gap, and edge values are all percentages of the text rect width.  Note that behaviour when this tag does not occur at the start of a line is undefined.&lt;br /&gt;
&lt;br /&gt;
== UI Scripting ==&lt;br /&gt;
You can attach a script to any UI control using the SCRIPT tag.  Events propagate up the UI object hierarchy to any attached script.  Generally you will use root object level scripts for general screen logic, and child-object scripts for more specific rendering components.&lt;br /&gt;
&lt;br /&gt;
The hook functions for UI scripts are:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_INIT()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called once when the screen is loaded.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_ACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is activated (shown) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_DEACTIVATE(id)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called when a screen is deactivated (hidden) by the game.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_RENDER(x, y, width, height, pass, name, flags)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called to allow scripts to do additional rendering on a control.  All screen params are in 1024x768 space.  The function is called twice each time the control is rendered, with the pass value set to 0 when called prior to default object rendering, and 1 when called after.  Returning 9999 will prevent the default rendering of the control.  flags - bit 0: pressed or selected (button only), bit 1: mouse over, bit 2: disabled, bit 3: invisible.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_HANDLE(data, event, id, name)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Receives events from controls when they are actioned.  The data parameter varies depending upon the control type, e.g. it is the region clicked in Region Map controls, or the clicked item in a list in a Listbox control.  The event varies, but is generally 0 for a left mouse action, 1 for a right.&lt;br /&gt;
The id is the id of the actioned control.  Use the IsUIObject system function to map this to a specific object name.  The name is the name of the owning object (e.g. the object to which the script is attached).&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_UPDATE(mousex, mousey, buttons, over, dragging, flags, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Called on the object update, and providing information on the current mouse position, button states, object the mouse is over, and any object being dragged.  The mouse coordinates are in 1024x768.  The buttons value is a bitmask, with bit 0 being the left button state, and bit 1 being the right.  The over and dragging values are object IDs as per the UI_OBJ_HANDLE function.  data is the control-specific data value, currently only listboxes return a value (the index of the currently moused over item, -1 if none).  Other control types always set this to zero.&lt;br /&gt;
The flags value can be one of the following values:&lt;br /&gt;
&lt;br /&gt;
0        - normal per tick update&lt;br /&gt;
1        - the dragging object has just been dropped&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION UI_OBJ_EVENT(id, event, data)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This is called when a script uses the UIEvent command to trigger and event on another control.  This can be used for inter-control communication.&lt;br /&gt;
&lt;br /&gt;
== Tutorial Popups ==&lt;br /&gt;
You can set up automated, one-time tutorial messages when screens are shown, or when a control is actioned.  These should be set up in DATA/TUT.TXT, with entries of the form:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[&amp;lt;object or screen name&amp;gt;]&lt;br /&gt;
POPUP &amp;lt;poupname&amp;gt;        // optional, name of the screen used for the popup, defaults to TUTORIAL&lt;br /&gt;
STRING &amp;lt;string tag&amp;gt;     // required string ID for the string to be shown (see below)&lt;br /&gt;
TEX &amp;lt;texture name&amp;gt;      // optional texture to be applied to the popup when used (see below)&lt;br /&gt;
TAG &amp;lt;value&amp;gt;             // optional tag value. Only show this popup when a TAG value is set in the mission chunk in the current campaign and the values match.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
[MainMenu]  // this is a screen&lt;br /&gt;
STRING IDS_WELCOME_MESSAGE&lt;br /&gt;
&lt;br /&gt;
[ScenEdUnitMode]  // this is a button&lt;br /&gt;
POPUP MyCustomPopup&lt;br /&gt;
STRING IDS_EXPLAIN_UNIT_EDITING&lt;br /&gt;
TEX MyCustomTexture&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The popup should have controls in it with names of the form &amp;lt;base&amp;gt;String, &amp;lt;base&amp;gt;Image, and &amp;lt;base&amp;gt;Quit - for example you will see that the default CORE/TUTORIAL.TXT file has controls TutorialString and TutorialQuit - the String and Image controls are optional, but Quit is always required and the game will throw an error if it is missing (as there would be no way to close the tutorial message).  The string and texture entries from the entry are applied to the String and Image controls respectively.&lt;br /&gt;
&lt;br /&gt;
You may set up a chunk for a given control or screen more than once, which will lead to them showing the first defined entry the first time it is seen/used, and the second the next time the player uses the control or enters the screen.  Each time an entry is shown this state is saved (in a local TUT.INF file) to prevent the tutorial popup being shown more than once.  Because of this state saving, you should always add new tutorial entries to the end of the file to avoid going out of sync with the saved data.&lt;br /&gt;
&lt;br /&gt;
= UI Defaults =&lt;br /&gt;
Certain UI global values are set via UI settings files.  The default values are in SYSTEM/UIDEFAULTS.TXT.  They are listed below.  Note that this file also includes any COLOURDICTIONARY chunk.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;TOOLTIPCOLOUR              // default tooltip colour&lt;br /&gt;
TOOLTIPOFFSETX             // X offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPOFFSETY             // Y offset of the tooltip from the cursor&lt;br /&gt;
TOOLTIPBORDER              // width of the border around the tooltip text&lt;br /&gt;
TOOLTIP9SLICESIZE          // 9 slice corner size in texture pixels &lt;br /&gt;
TOOLTIP9SLICEDRAWSIZE      // draw size for 9 slice corner&lt;br /&gt;
&lt;br /&gt;
= UI and Font Scaling =&lt;br /&gt;
Options values GlobalUIScale and GlobalFontScale.  They are in 1000s, so 1500 (e.g.) means make things 50% larger.  They are independent.&lt;br /&gt;
 &lt;br /&gt;
UI scaling is controlled from the UI files, and defaults to off.  In the top chunk, add an ALLOWSCALING tag to enable it.  Obviously screens which are fullscreen generally won't scale properly.&lt;br /&gt;
 &lt;br /&gt;
The game attempts to keep things on the screen, but this can be broken if there are objects that you have stored offscreen (for debug etc) - and so these should be tagged with a IGNOREWHENSCALING line.&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=553</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=553"/>
		<updated>2023-10-30T23:35:10Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Copy + Paste in Edit Boxes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=552</id>
		<title>Latest Additions</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Latest_Additions&amp;diff=552"/>
		<updated>2023-10-30T23:33:48Z</updated>

		<summary type="html">&lt;p&gt;Phil: /* Copy + Paste in Edit boxes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Copy + Paste in Edit Boxes =&lt;br /&gt;
You can now copy and paste in Edit boxes.  There is a new tag SELECTIONCOLOUR which allows you to alter the colour of the selection box displayed when selecting for copy.&lt;br /&gt;
You cannot copy from a password box.  You cannot paste over text (e.g. paste into a selection thus replacing it).&lt;br /&gt;
You can also copy from textmode listboxes (as used by the MP chat box).  This is only possible if you add an ALLOWCOPY tag to the UI control.  There is also a TEXTSELECTIONCOLOUR tag which can be set on these controls.&lt;br /&gt;
&lt;br /&gt;
= 4:3 Ratio UI overrides =&lt;br /&gt;
In the rare case where a UI file needs special formatting for 4:3 ratio screens, you can define a different UI file to be loaded where appropriate.  Simply create a folder called 43 in the same folder as the UI files.  Any file in the 43 folder, which has the same name as a file in the parent folder, will be loaded instead, when running at a resolution with a 4:3 aspect ratio or lower.&lt;br /&gt;
&lt;br /&gt;
= Pick Callback =&lt;br /&gt;
Tile. Use the following HELPERS.BSF callback to control picking/selection in battle.&lt;br /&gt;
 PICK_CALLBACK(blocking)&lt;br /&gt;
Where blocking is set to 1 when the mouse is over any UI block set with BlockUIArea during a render call.  Return 0 to pick normally, 1 to prevent picking/selection.&lt;br /&gt;
&lt;br /&gt;
= Custom Mouse Handling =&lt;br /&gt;
Tile. Callbacks exist for custom mouse handling.  These are&lt;br /&gt;
 MOUSE_CLICK_HANDLER(action, tilex, tiley)    // in HELPERS.BSF&lt;br /&gt;
 DEBUG_MOUSE_CLICK_HANDLER(action, tilex, tiley) // in DEBUG_HELPERS.BSF when enabled&lt;br /&gt;
They are triggered on mouse up.  action is 0 for LMB, 1 for RMB.  Return non-zero in MOUSE_CLICK_HANDLER to prevent normal mouse handling.&lt;br /&gt;
&lt;br /&gt;
= User Folder Redirection =&lt;br /&gt;
If the user places a REDIRECT.TXT file in their local folder (e.g. Documents/My Games/&amp;lt;game&amp;gt;) which contains the line&lt;br /&gt;
 FOLDER &amp;lt;fullpath&amp;gt;&lt;br /&gt;
Then the game will treat the provided folder as the user folder for this game.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Tooltips =&lt;br /&gt;
You can now enable automatic hotkey tooltips.  See the UI button documentation.&lt;br /&gt;
&lt;br /&gt;
= Hotkey Modifiers =&lt;br /&gt;
Can now have UI control hotkeys with SHIFT and/or CTRL modifiers.  See the UI documentation.&lt;br /&gt;
&lt;br /&gt;
= New Tile Callbacks =&lt;br /&gt;
Tile. New callbacks&lt;br /&gt;
&lt;br /&gt;
 // Allows for additional text to be added to skirmish descriptions in the MP creation screen.&lt;br /&gt;
 // Place any string to be added in the first UI string&lt;br /&gt;
 FUNCTION SKIRMISH_COMMENT_CALLBACK()&lt;br /&gt;
&lt;br /&gt;
 // Called immediately after loading the userdata when a game is loaded&lt;br /&gt;
 // skirmish param is zero or one.  Userdata is in the first work array.&lt;br /&gt;
 FUNCTION LOAD_USERDATA_CALLBACK(skirmish)&lt;br /&gt;
&lt;br /&gt;
= StartCampaign &amp;amp; ReplaceUnit Script Commands =&lt;br /&gt;
Tile. StartCampaign can now take no params at which point it loads the ||SKIRMISH campaign as per skirmish battles.  ReplaceUnit replaces one unit with another.  In order to handle any custom setup (esp anything which is used in animation callbacks) there is a REPLACE_CALLBACK(me) callback where any required data can be set up after the new replacement unit has been initialized but before we try and sync up animations etc.  So you will need to save out any specific attribs from the unit that you care about and then reset then in the callback (if needed) or after the ReplaceUnit call returns.&lt;br /&gt;
&lt;br /&gt;
= Screenshot/Movie Capture =&lt;br /&gt;
Updates:  there is now an onscreen flash when capturing a screenshot.  You can also place entries for SCREENSHOTSFX and MOVIESFX into the UIDefaults.txt file in System.  These should be numeric index values into the sfx list for sounds to be played when screenshotting, and when beginning a movie capture respectively.&lt;br /&gt;
&lt;br /&gt;
= Global saves =&lt;br /&gt;
You can now pass an empty string into Load/SaveVariableData and it will load and save from a GLOBAL_DATA.TXT file in (e.g.) My Documents/My Games/FieldOfGlory2.  This can be used to set up a global structure for persistent data across the game, e.g. hi scores or battles won.&lt;br /&gt;
&lt;br /&gt;
= Load Sequence Function =&lt;br /&gt;
Tile. If the script CORE/LOADINIT.BSF exists then the function LoadInit from within it will be called at the very start of the main loading sequence, immediately after the first loadbar frame is shown.&lt;br /&gt;
&lt;br /&gt;
= Progress Bars Accept KEEPSQUARE =&lt;br /&gt;
You can now use a KEEPSQUARE tag for progress bars if desired.&lt;br /&gt;
&lt;br /&gt;
= Global Orders =&lt;br /&gt;
Tile. You can now include global orders which do not require a unit to be selected.  These are defined in the CORE.BSF script, and should follow the template for standard unit orders (i.e. CHECK_, UIBUTTON_, etc functions must exist).  These orders use a CORE_ prefix, rather than TILE_, UNIT_, or ALL_.&lt;br /&gt;
&lt;br /&gt;
= Gamma Adjustment =&lt;br /&gt;
Two new commands allow for adjusting the gamma values when in fullscreen.  To allow for saving of the gamma value (or others) there are 3 additional Custom* options values available.  Custom1, Custom2, Custom3.  All default to zero.  Suggested values for gamma would be 0.5 to 2.0 or so, depending on the variation you wish to allow.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set the gamma value, if possible.  gamma is in 1000ths.&lt;br /&gt;
SetGamma(gamma)&lt;br /&gt;
&lt;br /&gt;
//returns 1 if the current setup allows for gamma adjustment (e.g. driver support, or because gamma requires fullscreen).&lt;br /&gt;
AllowsGamma()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Get/SetUnitString Script Commands =&lt;br /&gt;
Tile. New commands to allow a custom unicode string to be attached to a unit.&lt;br /&gt;
 //place the contents of the first UI string as a custom string for the unit. &lt;br /&gt;
 SetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
 //place the contents of the unit custom string into the first UI string.  Returns 0 if there is no custom string, 1 otherwise&lt;br /&gt;
 GetUnitString(me)&lt;br /&gt;
&lt;br /&gt;
= User Content Debugging =&lt;br /&gt;
Tile. When in DEBUGMODE is set to 2, the system will additionally load list_debug.txt into the user content list from the server.  This is to allow for simpler testing of user content from the server without polluting the release list.&lt;br /&gt;
&lt;br /&gt;
= GetSkirmishPoints &amp;amp; GetCurrentMod =&lt;br /&gt;
Tile. New script commands to fetch the currently set skirmish points, and to query the current mod.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//sets the first 4 values in the first work array with the current skirmish points values (fixed0, fixed1, select0, select1)&lt;br /&gt;
GetSkirmishPoints()&lt;br /&gt;
&lt;br /&gt;
//if a mod is selected, place the name of the current mod into the first UI string and return its index, otherwise return -1.  Always returns -1 in multiplayer.&lt;br /&gt;
GetCurrentMod()&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Modding Updates =&lt;br /&gt;
Tile.  Mods can now override S4F and their animation files for units.  They can also override scripts for AI, unit, HELPERS, and CORE BSF files.  NOTE: to package global mods, you need a ModsPackage named button on the mod UI panel.&lt;br /&gt;
&lt;br /&gt;
= Lobby Colouring Tweak =&lt;br /&gt;
Tile. You can now use the VALUE5 entry for the accept games list to define the RGB value for disabled games (where you do not have the necessary campaign etc).  Alpha is set to 0xFF by the game.  Zero uses the default colouring.&lt;br /&gt;
&lt;br /&gt;
= String Attribs =&lt;br /&gt;
Tile.  You can have up to 8 read-only strings attached to a squad template.  These must be defined in the squads file using tags ##0 to ##7.  The string data for each element must have 27 characters or less, and spaces are not permitted.  You can then retrieve these using the new command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the given attrib string into the first work string.  typeIndex is the index of the unit type. index is currently [0,7].&lt;br /&gt;
GetAttribString(typeIndex, index)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Note that the string returned will have been converted into upper case.&lt;br /&gt;
&lt;br /&gt;
= UpdateUserStringFromUI and GetUIEditboxToInt Script Commands =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//take the UI string from an editbox object and update it if it has changed (or is new).  Return 1 if a change has been made, zero otherwise.&lt;br /&gt;
UpdateUserStringFromUI(objectName, tag)&lt;br /&gt;
&lt;br /&gt;
//takes the contents of the UI editbox and converts them to a string.  If there are any non-numeric characters in the string, then the return value is invalidValue.  Skips leading and trailing whitespace.&lt;br /&gt;
GetUIEditboxToInt(objectName, invalidValue)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Review Battlefield After Battle =&lt;br /&gt;
Tile. You can now set up the UI to allow the user to review the battlefield after a battle ends.  To do this you should:&lt;br /&gt;
* Add a button the the EndBattle control called EndBattleReview&lt;br /&gt;
* Create a new UI screen to allow the user to exit after they have finished reviewing.  This screen should be called EndReview, and should include a button named EndReviewOK.  EndReview should not be modal, but should have the same HANDLER as EndBattle (DeployHandler).&lt;br /&gt;
This should allow the player to review the battlefield, with all units shown.&lt;br /&gt;
&lt;br /&gt;
= ShowUIListboxItem =&lt;br /&gt;
New script command which moves the viewable area (if needed) to show the given item.&lt;br /&gt;
 //move the UI listbox to show the given item index.  Scrolls unless immediate is non-zero, in which case it instantly changes the view&lt;br /&gt;
 ShowUIListboxItem(objectName, index, [immediate])&lt;br /&gt;
&lt;br /&gt;
= GetString Control Change =&lt;br /&gt;
If the UI object GetStringTitle exists, then the title text for the system GetString control will be placed there, rather than in the title of the GetString object window as per default.&lt;br /&gt;
&lt;br /&gt;
= DEPLOY_DRAG_CALLBACK =&lt;br /&gt;
Tile. Unit script function that is called each time a unit is moved by dragging when in deployment.&lt;br /&gt;
 FUNCTION DEPLOY_DRAG_CALLBACK(me, tilex, tiley)&lt;br /&gt;
&lt;br /&gt;
= Multiline for UI Edit Controls =&lt;br /&gt;
Adding a CHATMODE tag to edit controls will now allow them to contain more than one line.&lt;br /&gt;
&lt;br /&gt;
= Further INCLUDE Functionality for UI Files =&lt;br /&gt;
You can now use a prefix to rename included UI file components, allowing reuse of UI fragments. See here:[[UI]]&lt;br /&gt;
&lt;br /&gt;
= User Music Control =&lt;br /&gt;
Tile.  You can alter the music that is playing using the new script command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//switch to the denoted music track.  Must be [0,5] currently as per the MUSIC.TXT file order.&lt;br /&gt;
SwitchMusic(track)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Can be combined with the new tweak DisableDefaultMusic, which stops all hardcoded changes of music (NOTE: other than the initial playing of the main menu music, and some other changes back to the main menu music when internal code takes the UI back to the main menu).&lt;br /&gt;
&lt;br /&gt;
It is also worth reminding of the existence of the SetMusicFile command&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//set a music file to be loaded and used. Looks in local then core files. A ? as filename means leave the existing music entry.&lt;br /&gt;
SetMusicFile(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= New Script Commands: GetMapStyle &amp;amp; DeleteUserCampaign =&lt;br /&gt;
Tile.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;//place the current map style string into the first work string.&lt;br /&gt;
GetMapStyle()&lt;br /&gt;
&lt;br /&gt;
//delete a user campaign.  The filename is expected to include the CAMPAIGNS or MULTIPLAYER path element depending upon where the campaign is.  E.g. MULTIPLAYER/MYCAMPAIGN.  NOTE: it is good practice to prompt the user to confirm deletion.&lt;br /&gt;
DeleteUserCampaign(filename)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Including Templates in UI Files =&lt;br /&gt;
You can now include other files in UI files.  Note this should be used with care as objects with the same names are still prohibited.  All includes must be the first thing in the UI file.  Lines must be of the form&lt;br /&gt;
 #include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 include &amp;quot;file.txt&amp;quot;&lt;br /&gt;
The template files must be in DATA/UI/TEMPLATES&lt;br /&gt;
&lt;br /&gt;
= AreNewDownloads Script Command =&lt;br /&gt;
 //returns 1 if there are new user content downloads available, 0 otherwise&lt;br /&gt;
 AreNewDownloads()&lt;br /&gt;
&lt;br /&gt;
= Button Text Colour Updates =&lt;br /&gt;
You can now define different colours for buttons to use when they are being actioned.  These colours can be set globally in the UIDEFAULTS.TXT file using&lt;br /&gt;
 BUTTONOVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 BUTTONDISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
You can also over-ride these values on a per-button basis in the UI text file using&lt;br /&gt;
 OVERCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DOWNCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
 DISABLEDCOLOUR &amp;lt;hex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= PRESTARTEDITOR Callback =&lt;br /&gt;
Tile. There is now a callback when the editor starts.  This can be located in either or both the CORE.BSF and scenario scripts.  The function is of the same form as PRESTARTBATTLE:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION PreStartEditor(mode)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Older Entries =&lt;br /&gt;
[[Archive_1]]&lt;/div&gt;</summary>
		<author><name>Phil</name></author>
	</entry>
</feed>