<?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=Andrewg</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=Andrewg"/>
	<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php/Special:Contributions/Andrewg"/>
	<updated>2026-06-07T12:18:56Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.2</generator>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=535</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=535"/>
		<updated>2019-08-08T15:11:38Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Advanced Modding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[Empires Version]] for additional topics.&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
If you copied an existing scenario as above, your scenario should already contain a DATA\SCRIPTS\Events_Plugin.BSF containing one function, Event_EntryPoint(). Standard Empires events are found the Data\scripts\Events.BSF in the game installation folder.  You may refer to the events in this file as a reference when creating events.&lt;br /&gt;
&lt;br /&gt;
At the bottom of Events_Plugin, create a new function for your event, this function will be called at the end of each turn and will determine if the event should occur, what factions are affected, and apply the gameplay effects of the event.  By convention, the function name should start with EventCustom_ followed by a descriptive name for the event.  Once you have written your event function, add a call to it in the Event_EntryPoint function at the top of your Events_Plugin.&lt;br /&gt;
&lt;br /&gt;
For example, if you want to create an event that will give 100 metal once during the scenario to each faction with a 1% chance each turn, your file should like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION Event_EntryPoint()&lt;br /&gt;
{&lt;br /&gt;
	EventCustom_MetalStrike();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//// METAL STRIKE ////&lt;br /&gt;
&lt;br /&gt;
// turn to start checking for the event (0 based)&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_TURNSTART 1&lt;br /&gt;
&lt;br /&gt;
// % chance per turn per faction&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_CHANCE 1&lt;br /&gt;
&lt;br /&gt;
// amount of resource given&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_AMOUNT 100&lt;br /&gt;
&lt;br /&gt;
// record of which factions have received the event&lt;br /&gt;
int EvtCustom_MetalStrike[FACTION_MAX];&lt;br /&gt;
&lt;br /&gt;
FUNCTION EventCustom_MetalStrike()&lt;br /&gt;
{&lt;br /&gt;
	int facCount;&lt;br /&gt;
	int facIndex;&lt;br /&gt;
	int factionID;&lt;br /&gt;
	&lt;br /&gt;
	if (GetTurn() &amp;gt;= EVTCUSTOM_METALSTRIKE_TURNSTART)&lt;br /&gt;
	{&lt;br /&gt;
		// iterate over all factions&lt;br /&gt;
		facCount = GetNumFactions();	&lt;br /&gt;
		for (facIndex = 0; facIndex &amp;lt; facCount; facIndex++)&lt;br /&gt;
		{&lt;br /&gt;
			// has this faction already received this event (by index)&lt;br /&gt;
			if (EvtCustom_MetalStrike[facIndex] == FALSE)&lt;br /&gt;
			{&lt;br /&gt;
				// get the ID of this function&lt;br /&gt;
				factionID = GetFactionID(facIndex);&lt;br /&gt;
				&lt;br /&gt;
				// only applies to active factions, excluding independents&lt;br /&gt;
				if (Faction_IsWorldFactionOrInactive(factionID) == FALSE)&lt;br /&gt;
				{&lt;br /&gt;
					// has a chance to get a metal strike this turn&lt;br /&gt;
					if (Dice(100) &amp;lt;= EVTCUSTOM_METALSTRIKE_CHANCE)&lt;br /&gt;
					{&lt;br /&gt;
						// add the metal to the faction's stockpile&lt;br /&gt;
						Faction_AddResource(factionID, gResourceMetal, EVTCUSTOM_METALSTRIKE_AMOUNT);&lt;br /&gt;
						&lt;br /&gt;
						// send a message to the receiving faction&lt;br /&gt;
						Message_Faction_ChangeResourcePrivate(factionID, Faction_Politic_SeatOfPower(factionID), EVTCUSTOM_METALSTRIKE_AMOUNT, MSG_IMP_TOP, &amp;quot;IDS_MSG_EVENT_METAL_STRIKE&amp;quot;);&lt;br /&gt;
						&lt;br /&gt;
						// remember that this faction has already had a metal strike&lt;br /&gt;
						EvtCustom_MetalStrike[facIndex] = TRUE;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will also need to add the string to display for this event to your scenario's TEXT1.TXT file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;IDS_MSG_EVENT_METAL_STRIKE, &amp;quot;Prospectors discover metal deposits in %{1}u totalling %{0}u metal.&amp;quot;,&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
When modding gameplay scripts from Data\Scripts, you must also copy Data\Scripts\MAP.BSF to your modified scenario to ensure your changes are included, even if you do not require changes to MAP.BSF.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Empires contains a rudimentary editor for modifying or creating BAM files, which control the map. If you have started by copying the Grand Campaign, your scenario will be set up to load the shared Empires map, Data\Maps\AEP.BAM in the game install folder. If you open your scenario in the editor, changes you make will be saved to Data\Maps\AEP.BAM within your custom scenario. Note, you currently need to create an empty Maps folder within the Data folder of your scenario before you save the first time.&lt;br /&gt;
&lt;br /&gt;
If you have enabled DebugMode above, when you open the Options screen from the Main Menu the will be an Editor button at the top of the screen.  This editor has a small number of useful features. Select your scenario when prompted and click OK.&lt;br /&gt;
&lt;br /&gt;
Please note that there is no Undo feature in the Editor and saving and backing up frequently is strongly recommended if you are making multiple edits.&lt;br /&gt;
&lt;br /&gt;
=== Region Mode ===&lt;br /&gt;
&lt;br /&gt;
The default editor mode is Region Mode.  When you left click on the map to select a region, it will be highlighted in red and details will be displayed in the Region Properties panel on the right.&lt;br /&gt;
&lt;br /&gt;
The top section of Region Properties specifies which row in REGIONS.CSV corresponds to the selected region on the map.  Generally you will not need to change this unless you are creating a new map from scratch.&lt;br /&gt;
&lt;br /&gt;
The second section lists a number of properties of the region. They cannot be edited here, they are specified by REGIONS.CSV or other setup files described above.&lt;br /&gt;
&lt;br /&gt;
The third section is used to edit the connections between this region and its neighbors.  On the map, the connections to the selected region are visualized with colored arrows.&lt;br /&gt;
&lt;br /&gt;
If you right click on a region that is already connected to the current selection, it will be highlighted in purple and the Region Properties panel will update to let you Disconnect that region or change the connection 'terrain'.  Although all terrains are offered, the relevant choices are:&lt;br /&gt;
* Strait - for crossing between nearby land regions without transporting through the water region which separates them&lt;br /&gt;
* Big River Crossing - indicates regions are separated by a large river&lt;br /&gt;
* River Crossing - indicates regions are separated by a smaller river&lt;br /&gt;
* Land Interdiction - prevents land units from moving between regions when the rules would otherwise allow it&lt;br /&gt;
* Naval Interdiction - prevents naval units from moving between regions when the rules would otherwise allow it&lt;br /&gt;
* No Cost - standard connection, there is no extra cost or limitation for moving between regions&lt;br /&gt;
&lt;br /&gt;
See TERRAINS.CSV for the exact costs associated with the different connection types.&lt;br /&gt;
&lt;br /&gt;
If you right click on a region that is not connected to the current region, it will be highlighted in green and you will be able to Connect it from the Region Properties panel and then set the connection terrain.&lt;br /&gt;
&lt;br /&gt;
The bottom section of the Region Properties panel describes the anchor points defined for the selected region.  Anchor points are used to set the locations of many dynamic objects during the game.  The default anchor assignment is:&lt;br /&gt;
* 0: city&lt;br /&gt;
* 1: harbor&lt;br /&gt;
* 2: allied or neutral army&lt;br /&gt;
* 3: external wonder, 3d notifications, visual effects&lt;br /&gt;
* 4: second external wonder, second visual effect&lt;br /&gt;
* 5: icon&lt;br /&gt;
* 6: volcano&lt;br /&gt;
* 7: player army&lt;br /&gt;
* 8: overlay text&lt;br /&gt;
* 9: enemy army&lt;br /&gt;
&lt;br /&gt;
The anchor locations are displayed for the current region as either a yellow triangle, or another 3D model that indicates its use. To move an anchor, first select it either by clicking on its representation on the map or selecting it from the list. Then drag and drop it to the desired location.&lt;br /&gt;
&lt;br /&gt;
=== Border Mode ===&lt;br /&gt;
&lt;br /&gt;
The Border Mode contains a number of rudimentary tools for creating or modifying the boundaries of a region. The border mode has a palette of four tools, which perform a variety of related operations depending on the context, button, and key modifiers. The exact functionality is described on the left of the editor when you select the different tools.&lt;br /&gt;
&lt;br /&gt;
=== Unit Mode ===&lt;br /&gt;
&lt;br /&gt;
Unit Mode allows you to visualize initial armies created during scenario initialization as described above. You may select an army to view its details. The armies are not edited here, this is done in [[Empires_Modding#SETUP.CSV]]&lt;br /&gt;
&lt;br /&gt;
=== Scenario Properties ===&lt;br /&gt;
&lt;br /&gt;
This mode lists miscellaneous read only information about the scenario, determined by the setup files.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
In some cases, the map file could have a different name. The SCENARIO.TXT file at the root of your scenario contains a line specifying the name of the BAM file.&lt;br /&gt;
&lt;br /&gt;
See [[Empires_Terrain#Creating_a_Scenario]] for information on creating a new map using the editor.&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select the scenario to package from the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=534</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=534"/>
		<updated>2019-07-10T01:14:00Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* The Editor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[Empires Version]] for additional topics.&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
If you copied an existing scenario as above, your scenario should already contain a DATA\SCRIPTS\Events_Plugin.BSF containing one function, Event_EntryPoint(). Standard Empires events are found the Data\scripts\Events.BSF in the game installation folder.  You may refer to the events in this file as a reference when creating events.&lt;br /&gt;
&lt;br /&gt;
At the bottom of Events_Plugin, create a new function for your event, this function will be called at the end of each turn and will determine if the event should occur, what factions are affected, and apply the gameplay effects of the event.  By convention, the function name should start with EventCustom_ followed by a descriptive name for the event.  Once you have written your event function, add a call to it in the Event_EntryPoint function at the top of your Events_Plugin.&lt;br /&gt;
&lt;br /&gt;
For example, if you want to create an event that will give 100 metal once during the scenario to each faction with a 1% chance each turn, your file should like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION Event_EntryPoint()&lt;br /&gt;
{&lt;br /&gt;
	EventCustom_MetalStrike();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//// METAL STRIKE ////&lt;br /&gt;
&lt;br /&gt;
// turn to start checking for the event (0 based)&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_TURNSTART 1&lt;br /&gt;
&lt;br /&gt;
// % chance per turn per faction&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_CHANCE 1&lt;br /&gt;
&lt;br /&gt;
// amount of resource given&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_AMOUNT 100&lt;br /&gt;
&lt;br /&gt;
// record of which factions have received the event&lt;br /&gt;
int EvtCustom_MetalStrike[FACTION_MAX];&lt;br /&gt;
&lt;br /&gt;
FUNCTION EventCustom_MetalStrike()&lt;br /&gt;
{&lt;br /&gt;
	int facCount;&lt;br /&gt;
	int facIndex;&lt;br /&gt;
	int factionID;&lt;br /&gt;
	&lt;br /&gt;
	if (GetTurn() &amp;gt;= EVTCUSTOM_METALSTRIKE_TURNSTART)&lt;br /&gt;
	{&lt;br /&gt;
		// iterate over all factions&lt;br /&gt;
		facCount = GetNumFactions();	&lt;br /&gt;
		for (facIndex = 0; facIndex &amp;lt; facCount; facIndex++)&lt;br /&gt;
		{&lt;br /&gt;
			// has this faction already received this event (by index)&lt;br /&gt;
			if (EvtCustom_MetalStrike[facIndex] == FALSE)&lt;br /&gt;
			{&lt;br /&gt;
				// get the ID of this function&lt;br /&gt;
				factionID = GetFactionID(facIndex);&lt;br /&gt;
				&lt;br /&gt;
				// only applies to active factions, excluding independents&lt;br /&gt;
				if (Faction_IsWorldFactionOrInactive(factionID) == FALSE)&lt;br /&gt;
				{&lt;br /&gt;
					// has a chance to get a metal strike this turn&lt;br /&gt;
					if (Dice(100) &amp;lt;= EVTCUSTOM_METALSTRIKE_CHANCE)&lt;br /&gt;
					{&lt;br /&gt;
						// add the metal to the faction's stockpile&lt;br /&gt;
						Faction_AddResource(factionID, gResourceMetal, EVTCUSTOM_METALSTRIKE_AMOUNT);&lt;br /&gt;
						&lt;br /&gt;
						// send a message to the receiving faction&lt;br /&gt;
						Message_Faction_ChangeResourcePrivate(factionID, Faction_Politic_SeatOfPower(factionID), EVTCUSTOM_METALSTRIKE_AMOUNT, MSG_IMP_TOP, &amp;quot;IDS_MSG_EVENT_METAL_STRIKE&amp;quot;);&lt;br /&gt;
						&lt;br /&gt;
						// remember that this faction has already had a metal strike&lt;br /&gt;
						EvtCustom_MetalStrike[facIndex] = TRUE;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will also need to add the string to display for this event to your scenario's TEXT1.TXT file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;IDS_MSG_EVENT_METAL_STRIKE, &amp;quot;Prospectors discover metal deposits in %{1}u totalling %{0}u metal.&amp;quot;,&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Empires contains a rudimentary editor for modifying or creating BAM files, which control the map. If you have started by copying the Grand Campaign, your scenario will be set up to load the shared Empires map, Data\Maps\AEP.BAM in the game install folder. If you open your scenario in the editor, changes you make will be saved to Data\Maps\AEP.BAM within your custom scenario. Note, you currently need to create an empty Maps folder within the Data folder of your scenario before you save the first time.&lt;br /&gt;
&lt;br /&gt;
If you have enabled DebugMode above, when you open the Options screen from the Main Menu the will be an Editor button at the top of the screen.  This editor has a small number of useful features. Select your scenario when prompted and click OK.&lt;br /&gt;
&lt;br /&gt;
Please note that there is no Undo feature in the Editor and saving and backing up frequently is strongly recommended if you are making multiple edits.&lt;br /&gt;
&lt;br /&gt;
=== Region Mode ===&lt;br /&gt;
&lt;br /&gt;
The default editor mode is Region Mode.  When you left click on the map to select a region, it will be highlighted in red and details will be displayed in the Region Properties panel on the right.&lt;br /&gt;
&lt;br /&gt;
The top section of Region Properties specifies which row in REGIONS.CSV corresponds to the selected region on the map.  Generally you will not need to change this unless you are creating a new map from scratch.&lt;br /&gt;
&lt;br /&gt;
The second section lists a number of properties of the region. They cannot be edited here, they are specified by REGIONS.CSV or other setup files described above.&lt;br /&gt;
&lt;br /&gt;
The third section is used to edit the connections between this region and its neighbors.  On the map, the connections to the selected region are visualized with colored arrows.&lt;br /&gt;
&lt;br /&gt;
If you right click on a region that is already connected to the current selection, it will be highlighted in purple and the Region Properties panel will update to let you Disconnect that region or change the connection 'terrain'.  Although all terrains are offered, the relevant choices are:&lt;br /&gt;
* Strait - for crossing between nearby land regions without transporting through the water region which separates them&lt;br /&gt;
* Big River Crossing - indicates regions are separated by a large river&lt;br /&gt;
* River Crossing - indicates regions are separated by a smaller river&lt;br /&gt;
* Land Interdiction - prevents land units from moving between regions when the rules would otherwise allow it&lt;br /&gt;
* Naval Interdiction - prevents naval units from moving between regions when the rules would otherwise allow it&lt;br /&gt;
* No Cost - standard connection, there is no extra cost or limitation for moving between regions&lt;br /&gt;
&lt;br /&gt;
See TERRAINS.CSV for the exact costs associated with the different connection types.&lt;br /&gt;
&lt;br /&gt;
If you right click on a region that is not connected to the current region, it will be highlighted in green and you will be able to Connect it from the Region Properties panel and then set the connection terrain.&lt;br /&gt;
&lt;br /&gt;
The bottom section of the Region Properties panel describes the anchor points defined for the selected region.  Anchor points are used to set the locations of many dynamic objects during the game.  The default anchor assignment is:&lt;br /&gt;
* 0: city&lt;br /&gt;
* 1: harbor&lt;br /&gt;
* 2: allied or neutral army&lt;br /&gt;
* 3: external wonder, 3d notifications, visual effects&lt;br /&gt;
* 4: second external wonder, second visual effect&lt;br /&gt;
* 5: icon&lt;br /&gt;
* 6: volcano&lt;br /&gt;
* 7: player army&lt;br /&gt;
* 8: overlay text&lt;br /&gt;
* 9: enemy army&lt;br /&gt;
&lt;br /&gt;
The anchor locations are displayed for the current region as either a yellow triangle, or another 3D model that indicates its use. To move an anchor, first select it either by clicking on its representation on the map or selecting it from the list. Then drag and drop it to the desired location.&lt;br /&gt;
&lt;br /&gt;
=== Border Mode ===&lt;br /&gt;
&lt;br /&gt;
The Border Mode contains a number of rudimentary tools for creating or modifying the boundaries of a region. The border mode has a palette of four tools, which perform a variety of related operations depending on the context, button, and key modifiers. The exact functionality is described on the left of the editor when you select the different tools.&lt;br /&gt;
&lt;br /&gt;
=== Unit Mode ===&lt;br /&gt;
&lt;br /&gt;
Unit Mode allows you to visualize initial armies created during scenario initialization as described above. You may select an army to view its details. The armies are not edited here, this is done in [[Empires_Modding#SETUP.CSV]]&lt;br /&gt;
&lt;br /&gt;
=== Scenario Properties ===&lt;br /&gt;
&lt;br /&gt;
This mode lists miscellaneous read only information about the scenario, determined by the setup files.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
In some cases, the map file could have a different name. The SCENARIO.TXT file at the root of your scenario contains a line specifying the name of the BAM file.&lt;br /&gt;
&lt;br /&gt;
See [[Empires_Terrain#Creating_a_Scenario]] for information on creating a new map using the editor.&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select the scenario to package from the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=533</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=533"/>
		<updated>2019-07-09T22:36:54Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[Empires Version]] for additional topics.&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
If you copied an existing scenario as above, your scenario should already contain a DATA\SCRIPTS\Events_Plugin.BSF containing one function, Event_EntryPoint(). Standard Empires events are found the Data\scripts\Events.BSF in the game installation folder.  You may refer to the events in this file as a reference when creating events.&lt;br /&gt;
&lt;br /&gt;
At the bottom of Events_Plugin, create a new function for your event, this function will be called at the end of each turn and will determine if the event should occur, what factions are affected, and apply the gameplay effects of the event.  By convention, the function name should start with EventCustom_ followed by a descriptive name for the event.  Once you have written your event function, add a call to it in the Event_EntryPoint function at the top of your Events_Plugin.&lt;br /&gt;
&lt;br /&gt;
For example, if you want to create an event that will give 100 metal once during the scenario to each faction with a 1% chance each turn, your file should like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;FUNCTION Event_EntryPoint()&lt;br /&gt;
{&lt;br /&gt;
	EventCustom_MetalStrike();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//// METAL STRIKE ////&lt;br /&gt;
&lt;br /&gt;
// turn to start checking for the event (0 based)&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_TURNSTART 1&lt;br /&gt;
&lt;br /&gt;
// % chance per turn per faction&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_CHANCE 1&lt;br /&gt;
&lt;br /&gt;
// amount of resource given&lt;br /&gt;
#define EVTCUSTOM_METALSTRIKE_AMOUNT 100&lt;br /&gt;
&lt;br /&gt;
// record of which factions have received the event&lt;br /&gt;
int EvtCustom_MetalStrike[FACTION_MAX];&lt;br /&gt;
&lt;br /&gt;
FUNCTION EventCustom_MetalStrike()&lt;br /&gt;
{&lt;br /&gt;
	int facCount;&lt;br /&gt;
	int facIndex;&lt;br /&gt;
	int factionID;&lt;br /&gt;
	&lt;br /&gt;
	if (GetTurn() &amp;gt;= EVTCUSTOM_METALSTRIKE_TURNSTART)&lt;br /&gt;
	{&lt;br /&gt;
		// iterate over all factions&lt;br /&gt;
		facCount = GetNumFactions();	&lt;br /&gt;
		for (facIndex = 0; facIndex &amp;lt; facCount; facIndex++)&lt;br /&gt;
		{&lt;br /&gt;
			// has this faction already received this event (by index)&lt;br /&gt;
			if (EvtCustom_MetalStrike[facIndex] == FALSE)&lt;br /&gt;
			{&lt;br /&gt;
				// get the ID of this function&lt;br /&gt;
				factionID = GetFactionID(facIndex);&lt;br /&gt;
				&lt;br /&gt;
				// only applies to active factions, excluding independents&lt;br /&gt;
				if (Faction_IsWorldFactionOrInactive(factionID) == FALSE)&lt;br /&gt;
				{&lt;br /&gt;
					// has a chance to get a metal strike this turn&lt;br /&gt;
					if (Dice(100) &amp;lt;= EVTCUSTOM_METALSTRIKE_CHANCE)&lt;br /&gt;
					{&lt;br /&gt;
						// add the metal to the faction's stockpile&lt;br /&gt;
						Faction_AddResource(factionID, gResourceMetal, EVTCUSTOM_METALSTRIKE_AMOUNT);&lt;br /&gt;
						&lt;br /&gt;
						// send a message to the receiving faction&lt;br /&gt;
						Message_Faction_ChangeResourcePrivate(factionID, Faction_Politic_SeatOfPower(factionID), EVTCUSTOM_METALSTRIKE_AMOUNT, MSG_IMP_TOP, &amp;quot;IDS_MSG_EVENT_METAL_STRIKE&amp;quot;);&lt;br /&gt;
						&lt;br /&gt;
						// remember that this faction has already had a metal strike&lt;br /&gt;
						EvtCustom_MetalStrike[facIndex] = TRUE;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will also need to add the string to display for this event to your scenario's TEXT1.TXT file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;IDS_MSG_EVENT_METAL_STRIKE, &amp;quot;Prospectors discover metal deposits in %{1}u totalling %{0}u metal.&amp;quot;,&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
See [[Empires Terrain]] to get started with the editor.&lt;br /&gt;
&lt;br /&gt;
More coming soon...&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select the scenario to package from the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=532</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=532"/>
		<updated>2019-07-08T21:03:03Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[Empires Version]] for additional topics.&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon...&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
See [[Empires Terrain]] to get started with the editor.&lt;br /&gt;
&lt;br /&gt;
More coming soon...&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select the scenario to package from the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=531</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=531"/>
		<updated>2019-07-08T21:00:47Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &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;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=AEP_Modding&amp;diff=530</id>
		<title>AEP Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=AEP_Modding&amp;diff=530"/>
		<updated>2019-07-08T21:00:24Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Modding to Empires Modding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=529</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=529"/>
		<updated>2019-07-08T21:00:23Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Modding to Empires Modding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select the scenario to package from the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=528</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=528"/>
		<updated>2019-07-08T20:59:46Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[AEP 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;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=AEP_Hotkeys&amp;diff=527</id>
		<title>AEP Hotkeys</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=AEP_Hotkeys&amp;diff=527"/>
		<updated>2019-07-08T20:59:26Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Hotkeys to Empires Hotkeys&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires Hotkeys]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Hotkeys&amp;diff=526</id>
		<title>Empires Hotkeys</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Hotkeys&amp;diff=526"/>
		<updated>2019-07-08T20:59:25Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Hotkeys to Empires Hotkeys&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+I - 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>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Hotkeys&amp;diff=525</id>
		<title>Empires Hotkeys</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Hotkeys&amp;diff=525"/>
		<updated>2019-07-08T20:59:14Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &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+I - 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>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Terrain&amp;diff=524</id>
		<title>Empires Terrain</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Terrain&amp;diff=524"/>
		<updated>2019-07-08T20:56:28Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Empires Map and Terrain =&lt;br /&gt;
&lt;br /&gt;
== Creating a Scenario ==&lt;br /&gt;
To create a new scenario, click Editor from Options Screen and then the quill (Create a brand new campaign) button from the scenario selection screen.  Enter the scenario folder name and display name for the scenario.&lt;br /&gt;
&lt;br /&gt;
To use an existing map for this scenario, click Use map: &amp;lt;New Map&amp;gt; and choose a [[#BAM|BAM]] file.&lt;br /&gt;
&lt;br /&gt;
To create a new map, specify the following:&lt;br /&gt;
* [[#Map_Image|Map Image]]&lt;br /&gt;
* [[#Height_Map_Image|Height Map Image]]&lt;br /&gt;
* Height Scale - a multiplier applied to the height map values&lt;br /&gt;
* Logical Map Width - this is how large the map will appear to be in game, it is independent of the resolution of the map textures&lt;br /&gt;
* Logical Map Height - may be set smaller than the width to create a non-square map, the upper portion of the map textures will be used&lt;br /&gt;
* Import Borders from SVG (Advanced) - optionally specify an SVG file that contains border polygons to create initial borders. Note: SVG importing ONLY supports a list of polygons indicating a list of bordered regions.  There are many other ways a map could be constructed and saved in an SVG that will not be imported, if you are planning to use SVG importing, be sure that your software and approach results in this particular format.&lt;br /&gt;
&lt;br /&gt;
If you have not imported borders, or wish to edit borders, choose Border mode from the upper left palette in the editor and follow the directions below the palette.&lt;br /&gt;
&lt;br /&gt;
Before a map can be played, you will also need to associate the bordered regions with entries in an existing Regions.CSV file located in the Data folder in either the current scenario folder or the game folder.  Switch to the Region mode from the palette.  When you select a region, the Region Properties panel will be displayed.  To associate the region to a row in the table, select the row by name from the Template list.  You may also need to add or remove connections between regions to allow movement on the map (importing an SVG automatically creates connections between regions which share two or more consecutive border points).  This is also edited in the Region mode under Connections in the Region Properties panel.  The anchor points within a region can also be edited, the meanings of the anchors are specified by script and can be used to indicate city location, army locations, etc.&lt;br /&gt;
&lt;br /&gt;
The Unit mode and Scenario Properties modes of the editor are read-only modes displaying properties set by other CSV or script files.&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Unless otherwise specified, all map related files are located in either the Data/Maps folder within the current scenario folder (highest priority) or in the Data/Maps folder of the game folder (in which case they may be shared by multiple scenarios).&lt;br /&gt;
&lt;br /&gt;
=== SCENARIO.TXT ===&lt;br /&gt;
Each scenario requires a SCENARIO.TXT file in its root folder.  This file contains an entry which specifies which [[#BAM|BAM]] file to use as the map for the scenario.  It is created automatically when a scenario is created in the editor, and may be edited manually if required.&lt;br /&gt;
&lt;br /&gt;
=== BAM ===&lt;br /&gt;
The BAM file contains the map data.  It is created automatically by the editor.  Some fields in the [MAP] chunk of the file corresponding to the new map settings in [[#Creating_a_Scenario|Scenario Creation]] may be safely edited by hand.  Otherwise, the editor will normally be used to edit this file.&lt;br /&gt;
&lt;br /&gt;
=== Map Image ===&lt;br /&gt;
The map image is the base texture for the map and may be in any supported image format.  The RGB channels of this texture determine the color of the terrain (land and water).  If the [[#Detail_Map|terrain detail shader]] is used, the alpha channel is used to indicate which regions of the map are treated as land and which are treated as water.  Alpha 0 is water, alpha max is land.  If a smoother transition is required, providing intermediate alpha values will fade out water or terrain detail effects.&lt;br /&gt;
&lt;br /&gt;
=== Height Map Image ===&lt;br /&gt;
The height map image is used to determine the height values for the terrain.  It may be either a 32 bit TGA file (height is taken from the blue channel) or a RAW file.&lt;br /&gt;
&lt;br /&gt;
=== Normal Map ===&lt;br /&gt;
Optional.  Normal map applied over the entire map.  The filename is based on the map image filename &amp;lt;map_image&amp;gt;_N.ext.  It may be in any supported image format.&lt;br /&gt;
&lt;br /&gt;
=== Detail Map ===&lt;br /&gt;
Optional, requires a normal and specular map.  A map of the [[#Detail_Textures|terrain detail textures]] to be applied over the entire map.  The filename is based on the map image filename &amp;lt;map_image&amp;gt;_D.ext.  It may be in any supported image format (although good results may require an uncompressed format).  The red channel of the texture is used to indicate which of 8  detail textures to use.&lt;br /&gt;
* detail0: Red values 0 to 17 / 255&lt;br /&gt;
* detail1: Red values 18 to 53 / 255&lt;br /&gt;
* detail2: Red values 54 to 91 / 255&lt;br /&gt;
* detail3: Red values 92 to 127 / 255&lt;br /&gt;
* detail4: Red values 128 to 163 / 255&lt;br /&gt;
* detail5: Red values 164 to 201 / 255&lt;br /&gt;
* detail6: Red values 202 to 237 / 255&lt;br /&gt;
* detail7: Red values 238 to 255 / 255&lt;br /&gt;
&lt;br /&gt;
For best results and performance, detail0 - detail3 should be exactly the same resolution and detail4 - detail7 should be exactly the same resolution.&lt;br /&gt;
&lt;br /&gt;
=== Detail Textures ===&lt;br /&gt;
Optional. Detail textures blended with the [[#Map_Image|global map image]] and [[#Normal_Map|global normal map]] to provide additional terrain detail at high zoom levels without requiring a massive map images.  They are named detail0.tga to detail7.tga and detail0_N.tga to detail7_N.tga.  Only tga format is supported.  The detail textures are treated as greyscale images (only the red channel is used) and are tiled over the map image based on the [[#Detail_Map|detail map texture]] on land areas of the map.&lt;br /&gt;
&lt;br /&gt;
=== Alternate Weather Image ===&lt;br /&gt;
Optional. An alternate weather texture substituted for the [[#Map_Image|global map image]] based on gameplay values. The filename is based on the map image filename &amp;lt;map_image&amp;gt;_Weather.ext.&lt;br /&gt;
&lt;br /&gt;
=== CAMPAIGNVIEW.TXT ===&lt;br /&gt;
This file is located one level higher, in the shared or scenario Data folder. Refer to Data/CAMPAIGNVIEW.TXT in the game installation for reference. It allows several cosmetic changes to how the map is presented:&lt;br /&gt;
* ZOOM: default camera zoom distance&lt;br /&gt;
* ZOOMINLIMIT: closest camera zoom distance&lt;br /&gt;
* ZOOMLIMIT: farthest camera zoom distance&lt;br /&gt;
* CAMERAPITCH: camera pitch at the default zoom distance&lt;br /&gt;
* CAMERAPITCHMIN: camera pitch at the closest zoom distance&lt;br /&gt;
* CAMERAPITCHMAX: camera pitch at the farthest zoom distance, overrides CAMERAOVERHEAD&lt;br /&gt;
* CAMERAOVERHEAD: zoom distance to set the camera to be looking straight down, if CAMERAPITCHMAX is NOT specified&lt;br /&gt;
* FARPLANE: max draw distance&lt;br /&gt;
* CLEARCOLOUR: clear color in hex behind the map&lt;br /&gt;
* TERRAINSHADOW: non-0 to enable shadows cast by the terrain (useful if the Map Image doesn't contain prebaked shadows)&lt;br /&gt;
* TERRAINSHINE: glossiness of the map (0 to 1)&lt;br /&gt;
* OVERLAYWEIGHT: the strength of the map overlays (0 to 1)&lt;br /&gt;
* BANNERSCALE: the scale of the army banners on the map&lt;br /&gt;
* BANNEROFFSET: the distance (x and y) of the army banners from the army model&lt;br /&gt;
* BARRERSTEP: the distance (x and y) between banners at the same anchor point&lt;br /&gt;
* WORLDLIGHT: controls an ambient light (AMBIENT) and directional light (DIRECTION and COLOUR) for the map&lt;br /&gt;
* CLOUD#: controls a layer of cloud shown over the map&lt;br /&gt;
** COUNT: the number of clouds&lt;br /&gt;
** MIN_HEIGHT: the bottom of the cloud layer&lt;br /&gt;
** MAX_HEIGHT: the top of the cloud layer&lt;br /&gt;
** SIZE: average size of each cloud&lt;br /&gt;
** SPEED: average rotation speed of each cloud&lt;br /&gt;
** VARIATION: amount of variation between clouds (0 to 1)&lt;br /&gt;
** UNIFORM: if 0, the clouds are more dense near the edges of the map&lt;br /&gt;
** TEXTURE: the texture containing the cloud images&lt;br /&gt;
** ATLAS_SIZE: the number of images in TEXTURE to select from, vertically and horizontally (ie 2 means TEXTURE is a 2 x 2 atlas)&lt;br /&gt;
* DECORATION#: specifies the name file (FILE), size (SIZE), position (ANCHOR), and spin speed and direction (SPIN) of the 'decorations' shown on the map using SetRegionDecoration (ex objective markers)&lt;br /&gt;
* ROADS&lt;br /&gt;
** ANCHOR: which anchor point within the regions the road network goes through&lt;br /&gt;
** SIZE: the width of the roads in the road network overlay&lt;br /&gt;
** REQUIRED_TRANSPORT: the minimum TRANSPORT level in a pair of connected regions required to draw a road in the network overlay&lt;br /&gt;
* CITIES&lt;br /&gt;
** ANCHOR: which anchor point within the regions the city is drawn at&lt;br /&gt;
** SIZE: the scale for the city models&lt;br /&gt;
&lt;br /&gt;
== Slicing ==&lt;br /&gt;
Experimental. To support very high resolution textures, the Map Image, Normal Map, Specular Map, and Height Map Images may be sliced into multiple tiles.  The naming of these files is based on the untiled filename.  The top-left corner has the same name as the untiled filename, the remaining files have the x and y coordinates appended with _x_y.  For example, if the BAM specifies a map image texture of &amp;quot;map.dds&amp;quot;, the 2x2 tiled versions are:&lt;br /&gt;
* map.dds: top left (0,0)&lt;br /&gt;
* map_0_1.dds: lower left (0,1)&lt;br /&gt;
* map_1_0.dds: upper right (1,0)&lt;br /&gt;
* map_1_1.dds: lower right (1,1)&lt;br /&gt;
&lt;br /&gt;
If slicing is used, Map Image, Normal Map, Specular Map, and Alternate Weather Image must all use the same number of tiles.  Height Map Image tiling is independent.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=523</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=523"/>
		<updated>2019-07-08T20:55:45Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[AEP Modding]]&lt;br /&gt;
* [[Empires Scripting]]&lt;br /&gt;
* [[Empires Callbacks]]&lt;br /&gt;
* [[Empires BattleBoard]]&lt;br /&gt;
* [[Empires Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=AEP_Terrain&amp;diff=522</id>
		<title>AEP Terrain</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=AEP_Terrain&amp;diff=522"/>
		<updated>2019-07-08T20:55:24Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Terrain to Empires Terrain&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires Terrain]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Terrain&amp;diff=521</id>
		<title>Empires Terrain</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Terrain&amp;diff=521"/>
		<updated>2019-07-08T20:55:23Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Terrain to Empires Terrain&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AEP Map and Terrain =&lt;br /&gt;
&lt;br /&gt;
== Creating a Scenario ==&lt;br /&gt;
To create a new scenario, click Editor from Options Screen and then the quill (Create a brand new campaign) button from the scenario selection screen.  Enter the scenario folder name and display name for the scenario.&lt;br /&gt;
&lt;br /&gt;
To use an existing map for this scenario, click Use map: &amp;lt;New Map&amp;gt; and choose a [[#BAM|BAM]] file.&lt;br /&gt;
&lt;br /&gt;
To create a new map, specify the following:&lt;br /&gt;
* [[#Map_Image|Map Image]]&lt;br /&gt;
* [[#Height_Map_Image|Height Map Image]]&lt;br /&gt;
* Height Scale - a multiplier applied to the height map values&lt;br /&gt;
* Logical Map Width - this is how large the map will appear to be in game, it is independent of the resolution of the map textures&lt;br /&gt;
* Logical Map Height - may be set smaller than the width to create a non-square map, the upper portion of the map textures will be used&lt;br /&gt;
* Import Borders from SVG (Advanced) - optionally specify an SVG file that contains border polygons to create initial borders. Note: SVG importing ONLY supports a list of polygons indicating a list of bordered regions.  There are many other ways a map could be constructed and saved in an SVG that will not be imported, if you are planning to use SVG importing, be sure that your software and approach results in this particular format.&lt;br /&gt;
&lt;br /&gt;
If you have not imported borders, or wish to edit borders, choose Border mode from the upper left palette in the editor and follow the directions below the palette.&lt;br /&gt;
&lt;br /&gt;
Before a map can be played, you will also need to associate the bordered regions with entries in an existing Regions.CSV file located in the Data folder in either the current scenario folder or the game folder.  Switch to the Region mode from the palette.  When you select a region, the Region Properties panel will be displayed.  To associate the region to a row in the table, select the row by name from the Template list.  You may also need to add or remove connections between regions to allow movement on the map (importing an SVG automatically creates connections between regions which share two or more consecutive border points).  This is also edited in the Region mode under Connections in the Region Properties panel.  The anchor points within a region can also be edited, the meanings of the anchors are specified by script and can be used to indicate city location, army locations, etc.&lt;br /&gt;
&lt;br /&gt;
The Unit mode and Scenario Properties modes of the editor are read-only modes displaying properties set by other CSV or script files.&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Unless otherwise specified, all map related files are located in either the Data/Maps folder within the current scenario folder (highest priority) or in the Data/Maps folder of the game folder (in which case they may be shared by multiple scenarios).&lt;br /&gt;
&lt;br /&gt;
=== SCENARIO.TXT ===&lt;br /&gt;
Each scenario requires a SCENARIO.TXT file in its root folder.  This file contains an entry which specifies which [[#BAM|BAM]] file to use as the map for the scenario.  It is created automatically when a scenario is created in the editor, and may be edited manually if required.&lt;br /&gt;
&lt;br /&gt;
=== BAM ===&lt;br /&gt;
The BAM file contains the map data.  It is created automatically by the editor.  Some fields in the [MAP] chunk of the file corresponding to the new map settings in [[#Creating_a_Scenario|Scenario Creation]] may be safely edited by hand.  Otherwise, the editor will normally be used to edit this file.&lt;br /&gt;
&lt;br /&gt;
=== Map Image ===&lt;br /&gt;
The map image is the base texture for the map and may be in any supported image format.  The RGB channels of this texture determine the color of the terrain (land and water).  If the [[#Detail_Map|terrain detail shader]] is used, the alpha channel is used to indicate which regions of the map are treated as land and which are treated as water.  Alpha 0 is water, alpha max is land.  If a smoother transition is required, providing intermediate alpha values will fade out water or terrain detail effects.&lt;br /&gt;
&lt;br /&gt;
=== Height Map Image ===&lt;br /&gt;
The height map image is used to determine the height values for the terrain.  It may be either a 32 bit TGA file (height is taken from the blue channel) or a RAW file.&lt;br /&gt;
&lt;br /&gt;
=== Normal Map ===&lt;br /&gt;
Optional.  Normal map applied over the entire map.  The filename is based on the map image filename &amp;lt;map_image&amp;gt;_N.ext.  It may be in any supported image format.&lt;br /&gt;
&lt;br /&gt;
=== Detail Map ===&lt;br /&gt;
Optional, requires a normal and specular map.  A map of the [[#Detail_Textures|terrain detail textures]] to be applied over the entire map.  The filename is based on the map image filename &amp;lt;map_image&amp;gt;_D.ext.  It may be in any supported image format (although good results may require an uncompressed format).  The red channel of the texture is used to indicate which of 8  detail textures to use.&lt;br /&gt;
* detail0: Red values 0 to 17 / 255&lt;br /&gt;
* detail1: Red values 18 to 53 / 255&lt;br /&gt;
* detail2: Red values 54 to 91 / 255&lt;br /&gt;
* detail3: Red values 92 to 127 / 255&lt;br /&gt;
* detail4: Red values 128 to 163 / 255&lt;br /&gt;
* detail5: Red values 164 to 201 / 255&lt;br /&gt;
* detail6: Red values 202 to 237 / 255&lt;br /&gt;
* detail7: Red values 238 to 255 / 255&lt;br /&gt;
&lt;br /&gt;
For best results and performance, detail0 - detail3 should be exactly the same resolution and detail4 - detail7 should be exactly the same resolution.&lt;br /&gt;
&lt;br /&gt;
=== Detail Textures ===&lt;br /&gt;
Optional. Detail textures blended with the [[#Map_Image|global map image]] and [[#Normal_Map|global normal map]] to provide additional terrain detail at high zoom levels without requiring a massive map images.  They are named detail0.tga to detail7.tga and detail0_N.tga to detail7_N.tga.  Only tga format is supported.  The detail textures are treated as greyscale images (only the red channel is used) and are tiled over the map image based on the [[#Detail_Map|detail map texture]] on land areas of the map.&lt;br /&gt;
&lt;br /&gt;
=== Alternate Weather Image ===&lt;br /&gt;
Optional. An alternate weather texture substituted for the [[#Map_Image|global map image]] based on gameplay values. The filename is based on the map image filename &amp;lt;map_image&amp;gt;_Weather.ext.&lt;br /&gt;
&lt;br /&gt;
=== CAMPAIGNVIEW.TXT ===&lt;br /&gt;
This file is located one level higher, in the shared or scenario Data folder. Refer to Data/CAMPAIGNVIEW.TXT in the game installation for reference. It allows several cosmetic changes to how the map is presented:&lt;br /&gt;
* ZOOM: default camera zoom distance&lt;br /&gt;
* ZOOMINLIMIT: closest camera zoom distance&lt;br /&gt;
* ZOOMLIMIT: farthest camera zoom distance&lt;br /&gt;
* CAMERAPITCH: camera pitch at the default zoom distance&lt;br /&gt;
* CAMERAPITCHMIN: camera pitch at the closest zoom distance&lt;br /&gt;
* CAMERAPITCHMAX: camera pitch at the farthest zoom distance, overrides CAMERAOVERHEAD&lt;br /&gt;
* CAMERAOVERHEAD: zoom distance to set the camera to be looking straight down, if CAMERAPITCHMAX is NOT specified&lt;br /&gt;
* FARPLANE: max draw distance&lt;br /&gt;
* CLEARCOLOUR: clear color in hex behind the map&lt;br /&gt;
* TERRAINSHADOW: non-0 to enable shadows cast by the terrain (useful if the Map Image doesn't contain prebaked shadows)&lt;br /&gt;
* TERRAINSHINE: glossiness of the map (0 to 1)&lt;br /&gt;
* OVERLAYWEIGHT: the strength of the map overlays (0 to 1)&lt;br /&gt;
* BANNERSCALE: the scale of the army banners on the map&lt;br /&gt;
* BANNEROFFSET: the distance (x and y) of the army banners from the army model&lt;br /&gt;
* BARRERSTEP: the distance (x and y) between banners at the same anchor point&lt;br /&gt;
* WORLDLIGHT: controls an ambient light (AMBIENT) and directional light (DIRECTION and COLOUR) for the map&lt;br /&gt;
* CLOUD#: controls a layer of cloud shown over the map&lt;br /&gt;
** COUNT: the number of clouds&lt;br /&gt;
** MIN_HEIGHT: the bottom of the cloud layer&lt;br /&gt;
** MAX_HEIGHT: the top of the cloud layer&lt;br /&gt;
** SIZE: average size of each cloud&lt;br /&gt;
** SPEED: average rotation speed of each cloud&lt;br /&gt;
** VARIATION: amount of variation between clouds (0 to 1)&lt;br /&gt;
** UNIFORM: if 0, the clouds are more dense near the edges of the map&lt;br /&gt;
** TEXTURE: the texture containing the cloud images&lt;br /&gt;
** ATLAS_SIZE: the number of images in TEXTURE to select from, vertically and horizontally (ie 2 means TEXTURE is a 2 x 2 atlas)&lt;br /&gt;
* DECORATION#: specifies the name file (FILE), size (SIZE), position (ANCHOR), and spin speed and direction (SPIN) of the 'decorations' shown on the map using SetRegionDecoration (ex objective markers)&lt;br /&gt;
* ROADS&lt;br /&gt;
** ANCHOR: which anchor point within the regions the road network goes through&lt;br /&gt;
** SIZE: the width of the roads in the road network overlay&lt;br /&gt;
** REQUIRED_TRANSPORT: the minimum TRANSPORT level in a pair of connected regions required to draw a road in the network overlay&lt;br /&gt;
* CITIES&lt;br /&gt;
** ANCHOR: which anchor point within the regions the city is drawn at&lt;br /&gt;
** SIZE: the scale for the city models&lt;br /&gt;
&lt;br /&gt;
== Slicing ==&lt;br /&gt;
Experimental. To support very high resolution textures, the Map Image, Normal Map, Specular Map, and Height Map Images may be sliced into multiple tiles.  The naming of these files is based on the untiled filename.  The top-left corner has the same name as the untiled filename, the remaining files have the x and y coordinates appended with _x_y.  For example, if the BAM specifies a map image texture of &amp;quot;map.dds&amp;quot;, the 2x2 tiled versions are:&lt;br /&gt;
* map.dds: top left (0,0)&lt;br /&gt;
* map_0_1.dds: lower left (0,1)&lt;br /&gt;
* map_1_0.dds: upper right (1,0)&lt;br /&gt;
* map_1_1.dds: lower right (1,1)&lt;br /&gt;
&lt;br /&gt;
If slicing is used, Map Image, Normal Map, Specular Map, and Alternate Weather Image must all use the same number of tiles.  Height Map Image tiling is independent.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Terrain&amp;diff=520</id>
		<title>Empires Terrain</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Terrain&amp;diff=520"/>
		<updated>2019-07-08T20:55:10Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AEP Map and Terrain =&lt;br /&gt;
&lt;br /&gt;
== Creating a Scenario ==&lt;br /&gt;
To create a new scenario, click Editor from Options Screen and then the quill (Create a brand new campaign) button from the scenario selection screen.  Enter the scenario folder name and display name for the scenario.&lt;br /&gt;
&lt;br /&gt;
To use an existing map for this scenario, click Use map: &amp;lt;New Map&amp;gt; and choose a [[#BAM|BAM]] file.&lt;br /&gt;
&lt;br /&gt;
To create a new map, specify the following:&lt;br /&gt;
* [[#Map_Image|Map Image]]&lt;br /&gt;
* [[#Height_Map_Image|Height Map Image]]&lt;br /&gt;
* Height Scale - a multiplier applied to the height map values&lt;br /&gt;
* Logical Map Width - this is how large the map will appear to be in game, it is independent of the resolution of the map textures&lt;br /&gt;
* Logical Map Height - may be set smaller than the width to create a non-square map, the upper portion of the map textures will be used&lt;br /&gt;
* Import Borders from SVG (Advanced) - optionally specify an SVG file that contains border polygons to create initial borders. Note: SVG importing ONLY supports a list of polygons indicating a list of bordered regions.  There are many other ways a map could be constructed and saved in an SVG that will not be imported, if you are planning to use SVG importing, be sure that your software and approach results in this particular format.&lt;br /&gt;
&lt;br /&gt;
If you have not imported borders, or wish to edit borders, choose Border mode from the upper left palette in the editor and follow the directions below the palette.&lt;br /&gt;
&lt;br /&gt;
Before a map can be played, you will also need to associate the bordered regions with entries in an existing Regions.CSV file located in the Data folder in either the current scenario folder or the game folder.  Switch to the Region mode from the palette.  When you select a region, the Region Properties panel will be displayed.  To associate the region to a row in the table, select the row by name from the Template list.  You may also need to add or remove connections between regions to allow movement on the map (importing an SVG automatically creates connections between regions which share two or more consecutive border points).  This is also edited in the Region mode under Connections in the Region Properties panel.  The anchor points within a region can also be edited, the meanings of the anchors are specified by script and can be used to indicate city location, army locations, etc.&lt;br /&gt;
&lt;br /&gt;
The Unit mode and Scenario Properties modes of the editor are read-only modes displaying properties set by other CSV or script files.&lt;br /&gt;
&lt;br /&gt;
== Files ==&lt;br /&gt;
&lt;br /&gt;
Unless otherwise specified, all map related files are located in either the Data/Maps folder within the current scenario folder (highest priority) or in the Data/Maps folder of the game folder (in which case they may be shared by multiple scenarios).&lt;br /&gt;
&lt;br /&gt;
=== SCENARIO.TXT ===&lt;br /&gt;
Each scenario requires a SCENARIO.TXT file in its root folder.  This file contains an entry which specifies which [[#BAM|BAM]] file to use as the map for the scenario.  It is created automatically when a scenario is created in the editor, and may be edited manually if required.&lt;br /&gt;
&lt;br /&gt;
=== BAM ===&lt;br /&gt;
The BAM file contains the map data.  It is created automatically by the editor.  Some fields in the [MAP] chunk of the file corresponding to the new map settings in [[#Creating_a_Scenario|Scenario Creation]] may be safely edited by hand.  Otherwise, the editor will normally be used to edit this file.&lt;br /&gt;
&lt;br /&gt;
=== Map Image ===&lt;br /&gt;
The map image is the base texture for the map and may be in any supported image format.  The RGB channels of this texture determine the color of the terrain (land and water).  If the [[#Detail_Map|terrain detail shader]] is used, the alpha channel is used to indicate which regions of the map are treated as land and which are treated as water.  Alpha 0 is water, alpha max is land.  If a smoother transition is required, providing intermediate alpha values will fade out water or terrain detail effects.&lt;br /&gt;
&lt;br /&gt;
=== Height Map Image ===&lt;br /&gt;
The height map image is used to determine the height values for the terrain.  It may be either a 32 bit TGA file (height is taken from the blue channel) or a RAW file.&lt;br /&gt;
&lt;br /&gt;
=== Normal Map ===&lt;br /&gt;
Optional.  Normal map applied over the entire map.  The filename is based on the map image filename &amp;lt;map_image&amp;gt;_N.ext.  It may be in any supported image format.&lt;br /&gt;
&lt;br /&gt;
=== Detail Map ===&lt;br /&gt;
Optional, requires a normal and specular map.  A map of the [[#Detail_Textures|terrain detail textures]] to be applied over the entire map.  The filename is based on the map image filename &amp;lt;map_image&amp;gt;_D.ext.  It may be in any supported image format (although good results may require an uncompressed format).  The red channel of the texture is used to indicate which of 8  detail textures to use.&lt;br /&gt;
* detail0: Red values 0 to 17 / 255&lt;br /&gt;
* detail1: Red values 18 to 53 / 255&lt;br /&gt;
* detail2: Red values 54 to 91 / 255&lt;br /&gt;
* detail3: Red values 92 to 127 / 255&lt;br /&gt;
* detail4: Red values 128 to 163 / 255&lt;br /&gt;
* detail5: Red values 164 to 201 / 255&lt;br /&gt;
* detail6: Red values 202 to 237 / 255&lt;br /&gt;
* detail7: Red values 238 to 255 / 255&lt;br /&gt;
&lt;br /&gt;
For best results and performance, detail0 - detail3 should be exactly the same resolution and detail4 - detail7 should be exactly the same resolution.&lt;br /&gt;
&lt;br /&gt;
=== Detail Textures ===&lt;br /&gt;
Optional. Detail textures blended with the [[#Map_Image|global map image]] and [[#Normal_Map|global normal map]] to provide additional terrain detail at high zoom levels without requiring a massive map images.  They are named detail0.tga to detail7.tga and detail0_N.tga to detail7_N.tga.  Only tga format is supported.  The detail textures are treated as greyscale images (only the red channel is used) and are tiled over the map image based on the [[#Detail_Map|detail map texture]] on land areas of the map.&lt;br /&gt;
&lt;br /&gt;
=== Alternate Weather Image ===&lt;br /&gt;
Optional. An alternate weather texture substituted for the [[#Map_Image|global map image]] based on gameplay values. The filename is based on the map image filename &amp;lt;map_image&amp;gt;_Weather.ext.&lt;br /&gt;
&lt;br /&gt;
=== CAMPAIGNVIEW.TXT ===&lt;br /&gt;
This file is located one level higher, in the shared or scenario Data folder. Refer to Data/CAMPAIGNVIEW.TXT in the game installation for reference. It allows several cosmetic changes to how the map is presented:&lt;br /&gt;
* ZOOM: default camera zoom distance&lt;br /&gt;
* ZOOMINLIMIT: closest camera zoom distance&lt;br /&gt;
* ZOOMLIMIT: farthest camera zoom distance&lt;br /&gt;
* CAMERAPITCH: camera pitch at the default zoom distance&lt;br /&gt;
* CAMERAPITCHMIN: camera pitch at the closest zoom distance&lt;br /&gt;
* CAMERAPITCHMAX: camera pitch at the farthest zoom distance, overrides CAMERAOVERHEAD&lt;br /&gt;
* CAMERAOVERHEAD: zoom distance to set the camera to be looking straight down, if CAMERAPITCHMAX is NOT specified&lt;br /&gt;
* FARPLANE: max draw distance&lt;br /&gt;
* CLEARCOLOUR: clear color in hex behind the map&lt;br /&gt;
* TERRAINSHADOW: non-0 to enable shadows cast by the terrain (useful if the Map Image doesn't contain prebaked shadows)&lt;br /&gt;
* TERRAINSHINE: glossiness of the map (0 to 1)&lt;br /&gt;
* OVERLAYWEIGHT: the strength of the map overlays (0 to 1)&lt;br /&gt;
* BANNERSCALE: the scale of the army banners on the map&lt;br /&gt;
* BANNEROFFSET: the distance (x and y) of the army banners from the army model&lt;br /&gt;
* BARRERSTEP: the distance (x and y) between banners at the same anchor point&lt;br /&gt;
* WORLDLIGHT: controls an ambient light (AMBIENT) and directional light (DIRECTION and COLOUR) for the map&lt;br /&gt;
* CLOUD#: controls a layer of cloud shown over the map&lt;br /&gt;
** COUNT: the number of clouds&lt;br /&gt;
** MIN_HEIGHT: the bottom of the cloud layer&lt;br /&gt;
** MAX_HEIGHT: the top of the cloud layer&lt;br /&gt;
** SIZE: average size of each cloud&lt;br /&gt;
** SPEED: average rotation speed of each cloud&lt;br /&gt;
** VARIATION: amount of variation between clouds (0 to 1)&lt;br /&gt;
** UNIFORM: if 0, the clouds are more dense near the edges of the map&lt;br /&gt;
** TEXTURE: the texture containing the cloud images&lt;br /&gt;
** ATLAS_SIZE: the number of images in TEXTURE to select from, vertically and horizontally (ie 2 means TEXTURE is a 2 x 2 atlas)&lt;br /&gt;
* DECORATION#: specifies the name file (FILE), size (SIZE), position (ANCHOR), and spin speed and direction (SPIN) of the 'decorations' shown on the map using SetRegionDecoration (ex objective markers)&lt;br /&gt;
* ROADS&lt;br /&gt;
** ANCHOR: which anchor point within the regions the road network goes through&lt;br /&gt;
** SIZE: the width of the roads in the road network overlay&lt;br /&gt;
** REQUIRED_TRANSPORT: the minimum TRANSPORT level in a pair of connected regions required to draw a road in the network overlay&lt;br /&gt;
* CITIES&lt;br /&gt;
** ANCHOR: which anchor point within the regions the city is drawn at&lt;br /&gt;
** SIZE: the scale for the city models&lt;br /&gt;
&lt;br /&gt;
== Slicing ==&lt;br /&gt;
Experimental. To support very high resolution textures, the Map Image, Normal Map, Specular Map, and Height Map Images may be sliced into multiple tiles.  The naming of these files is based on the untiled filename.  The top-left corner has the same name as the untiled filename, the remaining files have the x and y coordinates appended with _x_y.  For example, if the BAM specifies a map image texture of &amp;quot;map.dds&amp;quot;, the 2x2 tiled versions are:&lt;br /&gt;
* map.dds: top left (0,0)&lt;br /&gt;
* map_0_1.dds: lower left (0,1)&lt;br /&gt;
* map_1_0.dds: upper right (1,0)&lt;br /&gt;
* map_1_1.dds: lower right (1,1)&lt;br /&gt;
&lt;br /&gt;
If slicing is used, Map Image, Normal Map, Specular Map, and Alternate Weather Image must all use the same number of tiles.  Height Map Image tiling is independent.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=519</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=519"/>
		<updated>2019-07-08T20:10:20Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Empires Scripting]]&lt;br /&gt;
* [[Empires Callbacks]]&lt;br /&gt;
* [[Empires BattleBoard]]&lt;br /&gt;
* [[AEP Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;br /&gt;
* [[AEP Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=BattleBoard&amp;diff=518</id>
		<title>BattleBoard</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=BattleBoard&amp;diff=518"/>
		<updated>2019-07-08T20:09:58Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page BattleBoard to Empires BattleBoard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires BattleBoard]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_BattleBoard&amp;diff=517</id>
		<title>Empires BattleBoard</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_BattleBoard&amp;diff=517"/>
		<updated>2019-07-08T20:09:57Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page BattleBoard to Empires BattleBoard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== UI ==&lt;br /&gt;
&lt;br /&gt;
There is a custom 3d UI object for displaying a battle board which .  It can be added to a UI by adding a &amp;quot;CUSTOM&amp;quot; type object to a UI with the additional tag &amp;quot;BATTLEBOARD&amp;quot; and a number of optional parameters to control formatting and behaviour.  For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[BattleSummary3D]&lt;br /&gt;
TYPE Custom&lt;br /&gt;
BattleBoard&lt;br /&gt;
WIDTH 868&lt;br /&gt;
HEIGHT 618&lt;br /&gt;
DX 0&lt;br /&gt;
DY 0&lt;br /&gt;
MINLINES 3&lt;br /&gt;
MINLINELENGTH 4&lt;br /&gt;
UNITSPACING 8&lt;br /&gt;
CENTERGAP 12&lt;br /&gt;
ASSETSCALE 7&lt;br /&gt;
GRIDEMPTY BattleGrid.tga&lt;br /&gt;
GRIDUNIT BattleGrid.tga&lt;br /&gt;
GRIDTARGET BattleGridTarget.tga&lt;br /&gt;
GRIDATTACKER BattleGridAttack.tga&lt;br /&gt;
FILE UI_BATTLE/Battlefield_Default.dds&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* MINLINES is the minimum number of battle lines per side to show on the battle board regardless of the number of units present (the view will zoom out to show additional lines if required)&lt;br /&gt;
* MINLINELENGTH is the minimum number of slots per wing to show on the battle board regardless of the number of units present (the view will zoom out to show additional lines if required)&lt;br /&gt;
* UNITSPACING is the distance between units&lt;br /&gt;
* CENTERGAP is an additional space between the front lines of opposing armies&lt;br /&gt;
* ASSETSCALE is a scale factor for the units (the scale used the AssetScale from UNITS.CSV in thousandths, divided by this value)&lt;br /&gt;
* GRIDEMPTY, GRIDUNIT, GRIDTARGET, and GRIDATTACKER are textures displayed over the ground to highlight empty grids, inactive units, targetted units, and attacking units respectively&lt;br /&gt;
* FILE is the default terrain texture to use (if not specified by script)&lt;br /&gt;
&lt;br /&gt;
== Scripting ==&lt;br /&gt;
&lt;br /&gt;
See BATTLESCRIPT.TXT for descriptions of commands to set up a BattleBoard UI, add units, play animations, move units, and display text with the units.  Relevant commands start with &amp;quot;Battle3D&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Squads ==&lt;br /&gt;
&lt;br /&gt;
Battle3DAddUnit takes a squadType, which is the name of a row in SQUADS.CSV which indicates the asset name, squad size, scale, and other display parameters for the 3D model.  This table is also used for displaying groups on the map, although they are always shown as a single unit on the map.&lt;br /&gt;
&lt;br /&gt;
Placement of squad members is controlled by FORMATIONS.TXT, there is a chunk for each squad size indicating the placement of the member (x and y coordinates, -1 to 1) in the battle grid.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=516</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=516"/>
		<updated>2019-07-08T20:07:54Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Empires Scripting]]&lt;br /&gt;
* [[Empires Callbacks]]&lt;br /&gt;
* [[BattleBoard]]&lt;br /&gt;
* [[AEP Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;br /&gt;
* [[AEP Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=AEP_Callbacks&amp;diff=515</id>
		<title>AEP Callbacks</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=AEP_Callbacks&amp;diff=515"/>
		<updated>2019-07-08T20:07:32Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Callbacks to Empires Callbacks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires Callbacks]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Callbacks&amp;diff=514</id>
		<title>Empires Callbacks</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Callbacks&amp;diff=514"/>
		<updated>2019-07-08T20:07:31Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Callbacks to Empires Callbacks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Map.bsf callbacks ==&lt;br /&gt;
&lt;br /&gt;
=== InitMap ===&lt;br /&gt;
Called when a new game is started.  Also called each time the scenario is opened in the editor. &lt;br /&gt;
&lt;br /&gt;
=== InitFinal ===&lt;br /&gt;
Called when a new game is started, immediately after InitScenario.&lt;br /&gt;
&lt;br /&gt;
=== StartMap(flags) ===&lt;br /&gt;
Called each time the scenario is opened (new game, loading a saved game, loading the scenario in the editor).&lt;br /&gt;
&lt;br /&gt;
Under some circumstances, StartMap can be called again during a play session, for example when a snapshot or replay state from an older play session is loaded. Bit 0 of the flags parameter will be set when this is the case, although generally the game should respond the same way.&lt;br /&gt;
&lt;br /&gt;
=== StartTurn ===&lt;br /&gt;
Called at the beginning of the planning phase of each turn.&lt;br /&gt;
&lt;br /&gt;
=== EndTurn ===&lt;br /&gt;
Called at the end of the resolution phase of each turn. Happens during the TurnResolveComplete command.&lt;br /&gt;
&lt;br /&gt;
=== UpdateMap(tick) ===&lt;br /&gt;
Called each frame.  If the tick parameter is 0, it means that this is an 'extra' frame because the game is rendering faster than its 'logical' framerate (30 fps).  Things that should happen at a constant speed (such turn resolution) should only happen if tick is 1, things that should happen as fast as possible (such as UI handling) should happen regardless of tick.  In practice, there should be very few places you need to look at the tick parameter.&lt;br /&gt;
&lt;br /&gt;
=== UpdateAI(faction) ===&lt;br /&gt;
Called for each AI controlled faction until it returns a non-zero value.  It is expected to run a small slice AI planning each call.  Called after UpdateScenario.  AI factions which have the INACTIVE attribute set to non-zero will be skipped.&lt;br /&gt;
&lt;br /&gt;
=== RenderMap ===&lt;br /&gt;
Called each frame after all of the update callbacks.  Primarily used for drawing UI elements over the map&lt;br /&gt;
&lt;br /&gt;
=== StartGroupVisuals(id) ===&lt;br /&gt;
Expected to set up the visuals for a group (including call SetGroupAsset).  Called at various points during game flow (expect it to be called multiple times as needed for the same group).  Must not modify gameplay values for object.&lt;br /&gt;
&lt;br /&gt;
=== StartStructureVisuals(id) ===&lt;br /&gt;
Expected to set up the visuals for a structure (including call SetStructureAsset).   Called at various points during game flow (expect it to be called multiple times as needed for the same structure).  Must not modify gameplay values for object.&lt;br /&gt;
&lt;br /&gt;
=== PathfindingData(region, group, ...) ===&lt;br /&gt;
Request for connection info for a group leaving a region.  For each region the group can enter from the requested region, the script must call SetPathfindingData.&lt;br /&gt;
&lt;br /&gt;
=== UI_UPDATE_GROUP(groupID, zoom, mouseX, mouseY, buttons) ===&lt;br /&gt;
Called once per frame for each group visible on the map to update the UIGroup layout for the current frame.  zoom is the height of the camera above the ground.  Return &amp;lt;= 0 if there is nothing to be drawn.  If the mouse is over any visible component of the UI, GetMouseGroup will return that group ID as it would if the mouse was over the group's on-map 3d object.  The root of the UI is automatically placed to draw immediately below the base of the group's on-map 3d object.&lt;br /&gt;
&lt;br /&gt;
== Scenario.bsf callbacks ==&lt;br /&gt;
&lt;br /&gt;
=== InitScenario ===&lt;br /&gt;
Called when a new game is started, immediately after InitMap.&lt;br /&gt;
&lt;br /&gt;
=== StartScenario(flags) ===&lt;br /&gt;
Called each time the scenario is opened (new game, loading a saved game), immediately after StartMap.  The flags parameter has the same meaning as in StartMap.&lt;br /&gt;
&lt;br /&gt;
=== StartTurn ===&lt;br /&gt;
Call each turn, immediately after Map.bsf StartTurn&lt;br /&gt;
&lt;br /&gt;
=== EndTurn ===&lt;br /&gt;
Called each turn, immediately before Map.bsf EndTurn. Happens during the TurnResolveComplete command.&lt;br /&gt;
&lt;br /&gt;
=== UpdateScenario ===&lt;br /&gt;
Called each frame, immediately after UpdateMap&lt;br /&gt;
&lt;br /&gt;
=== RenderScenario ===&lt;br /&gt;
Called each frame after, immediately after RenderMap&lt;br /&gt;
&lt;br /&gt;
== Callback sequence ==&lt;br /&gt;
&lt;br /&gt;
=== New Game Example ===&lt;br /&gt;
&lt;br /&gt;
# InitMap&lt;br /&gt;
# InitScenario&lt;br /&gt;
# InitFinal&lt;br /&gt;
# StartMap&lt;br /&gt;
# StartScenario&lt;br /&gt;
# StartRegionVisuals x N&lt;br /&gt;
# StartGroupVisuals x N&lt;br /&gt;
# show PreScenario UI (single player)&lt;br /&gt;
## UpdateMap&lt;br /&gt;
## UpdateScenario&lt;br /&gt;
## repeat until script calls StartScenario command&lt;br /&gt;
# StartTurn in Map.bsf&lt;br /&gt;
# StartTurn in Scenario.bsf&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# UpdateScenario&lt;br /&gt;
# RenderMap&lt;br /&gt;
# RenderScenario&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# ...&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# UpdateScenario&lt;br /&gt;
# UpdateAI&lt;br /&gt;
# ...&lt;br /&gt;
# EndTurn in Scenario.bsf&lt;br /&gt;
# EndTurn in Map.bsf&lt;br /&gt;
# StartTurn in Map.bsf&lt;br /&gt;
# StartTurn in Scenario.bsf&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# ...&lt;br /&gt;
&lt;br /&gt;
=== Loading Saved Game Example ===&lt;br /&gt;
&lt;br /&gt;
# StartMap&lt;br /&gt;
# StartScenario&lt;br /&gt;
# StartStructureVisuals x X&lt;br /&gt;
# StartGroupVisuals x X&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# UpdateScenario&lt;br /&gt;
# RenderMap&lt;br /&gt;
# RenderScenario&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# ...&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Callbacks&amp;diff=513</id>
		<title>Empires Callbacks</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Callbacks&amp;diff=513"/>
		<updated>2019-07-08T20:07:18Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Map.bsf callbacks ==&lt;br /&gt;
&lt;br /&gt;
=== InitMap ===&lt;br /&gt;
Called when a new game is started.  Also called each time the scenario is opened in the editor. &lt;br /&gt;
&lt;br /&gt;
=== InitFinal ===&lt;br /&gt;
Called when a new game is started, immediately after InitScenario.&lt;br /&gt;
&lt;br /&gt;
=== StartMap(flags) ===&lt;br /&gt;
Called each time the scenario is opened (new game, loading a saved game, loading the scenario in the editor).&lt;br /&gt;
&lt;br /&gt;
Under some circumstances, StartMap can be called again during a play session, for example when a snapshot or replay state from an older play session is loaded. Bit 0 of the flags parameter will be set when this is the case, although generally the game should respond the same way.&lt;br /&gt;
&lt;br /&gt;
=== StartTurn ===&lt;br /&gt;
Called at the beginning of the planning phase of each turn.&lt;br /&gt;
&lt;br /&gt;
=== EndTurn ===&lt;br /&gt;
Called at the end of the resolution phase of each turn. Happens during the TurnResolveComplete command.&lt;br /&gt;
&lt;br /&gt;
=== UpdateMap(tick) ===&lt;br /&gt;
Called each frame.  If the tick parameter is 0, it means that this is an 'extra' frame because the game is rendering faster than its 'logical' framerate (30 fps).  Things that should happen at a constant speed (such turn resolution) should only happen if tick is 1, things that should happen as fast as possible (such as UI handling) should happen regardless of tick.  In practice, there should be very few places you need to look at the tick parameter.&lt;br /&gt;
&lt;br /&gt;
=== UpdateAI(faction) ===&lt;br /&gt;
Called for each AI controlled faction until it returns a non-zero value.  It is expected to run a small slice AI planning each call.  Called after UpdateScenario.  AI factions which have the INACTIVE attribute set to non-zero will be skipped.&lt;br /&gt;
&lt;br /&gt;
=== RenderMap ===&lt;br /&gt;
Called each frame after all of the update callbacks.  Primarily used for drawing UI elements over the map&lt;br /&gt;
&lt;br /&gt;
=== StartGroupVisuals(id) ===&lt;br /&gt;
Expected to set up the visuals for a group (including call SetGroupAsset).  Called at various points during game flow (expect it to be called multiple times as needed for the same group).  Must not modify gameplay values for object.&lt;br /&gt;
&lt;br /&gt;
=== StartStructureVisuals(id) ===&lt;br /&gt;
Expected to set up the visuals for a structure (including call SetStructureAsset).   Called at various points during game flow (expect it to be called multiple times as needed for the same structure).  Must not modify gameplay values for object.&lt;br /&gt;
&lt;br /&gt;
=== PathfindingData(region, group, ...) ===&lt;br /&gt;
Request for connection info for a group leaving a region.  For each region the group can enter from the requested region, the script must call SetPathfindingData.&lt;br /&gt;
&lt;br /&gt;
=== UI_UPDATE_GROUP(groupID, zoom, mouseX, mouseY, buttons) ===&lt;br /&gt;
Called once per frame for each group visible on the map to update the UIGroup layout for the current frame.  zoom is the height of the camera above the ground.  Return &amp;lt;= 0 if there is nothing to be drawn.  If the mouse is over any visible component of the UI, GetMouseGroup will return that group ID as it would if the mouse was over the group's on-map 3d object.  The root of the UI is automatically placed to draw immediately below the base of the group's on-map 3d object.&lt;br /&gt;
&lt;br /&gt;
== Scenario.bsf callbacks ==&lt;br /&gt;
&lt;br /&gt;
=== InitScenario ===&lt;br /&gt;
Called when a new game is started, immediately after InitMap.&lt;br /&gt;
&lt;br /&gt;
=== StartScenario(flags) ===&lt;br /&gt;
Called each time the scenario is opened (new game, loading a saved game), immediately after StartMap.  The flags parameter has the same meaning as in StartMap.&lt;br /&gt;
&lt;br /&gt;
=== StartTurn ===&lt;br /&gt;
Call each turn, immediately after Map.bsf StartTurn&lt;br /&gt;
&lt;br /&gt;
=== EndTurn ===&lt;br /&gt;
Called each turn, immediately before Map.bsf EndTurn. Happens during the TurnResolveComplete command.&lt;br /&gt;
&lt;br /&gt;
=== UpdateScenario ===&lt;br /&gt;
Called each frame, immediately after UpdateMap&lt;br /&gt;
&lt;br /&gt;
=== RenderScenario ===&lt;br /&gt;
Called each frame after, immediately after RenderMap&lt;br /&gt;
&lt;br /&gt;
== Callback sequence ==&lt;br /&gt;
&lt;br /&gt;
=== New Game Example ===&lt;br /&gt;
&lt;br /&gt;
# InitMap&lt;br /&gt;
# InitScenario&lt;br /&gt;
# InitFinal&lt;br /&gt;
# StartMap&lt;br /&gt;
# StartScenario&lt;br /&gt;
# StartRegionVisuals x N&lt;br /&gt;
# StartGroupVisuals x N&lt;br /&gt;
# show PreScenario UI (single player)&lt;br /&gt;
## UpdateMap&lt;br /&gt;
## UpdateScenario&lt;br /&gt;
## repeat until script calls StartScenario command&lt;br /&gt;
# StartTurn in Map.bsf&lt;br /&gt;
# StartTurn in Scenario.bsf&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# UpdateScenario&lt;br /&gt;
# RenderMap&lt;br /&gt;
# RenderScenario&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# ...&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# UpdateScenario&lt;br /&gt;
# UpdateAI&lt;br /&gt;
# ...&lt;br /&gt;
# EndTurn in Scenario.bsf&lt;br /&gt;
# EndTurn in Map.bsf&lt;br /&gt;
# StartTurn in Map.bsf&lt;br /&gt;
# StartTurn in Scenario.bsf&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# ...&lt;br /&gt;
&lt;br /&gt;
=== Loading Saved Game Example ===&lt;br /&gt;
&lt;br /&gt;
# StartMap&lt;br /&gt;
# StartScenario&lt;br /&gt;
# StartStructureVisuals x X&lt;br /&gt;
# StartGroupVisuals x X&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# UpdateScenario&lt;br /&gt;
# RenderMap&lt;br /&gt;
# RenderScenario&lt;br /&gt;
# UpdateMap&lt;br /&gt;
# ...&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=512</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=512"/>
		<updated>2019-07-08T20:04:13Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Empires Scripting]]&lt;br /&gt;
* [[AEP Callbacks]]&lt;br /&gt;
* [[BattleBoard]]&lt;br /&gt;
* [[AEP Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;br /&gt;
* [[AEP Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=AEP_Scripting&amp;diff=511</id>
		<title>AEP Scripting</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=AEP_Scripting&amp;diff=511"/>
		<updated>2019-07-08T20:03:41Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Scripting to Empires Scripting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires Scripting]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Scripting&amp;diff=510</id>
		<title>Empires Scripting</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Scripting&amp;diff=510"/>
		<updated>2019-07-08T20:03:41Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Scripting to Empires Scripting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the general [[Scripting]] page for a description of the Archon scripting language.  See My Games\FieldOfGloryEmpires\AUTODOCS\BATTLESCRIPT.TXT for definitive script command descriptions relevant to Empires.&lt;br /&gt;
&lt;br /&gt;
Also output to the AUTODOCS folder is ARCHON.XML, a language definition compatible with Notepad++ (note that if the language definition is updated, the defined language must be removed and re-imported into Np++, it will not reload it automatically).&lt;br /&gt;
&lt;br /&gt;
== Pathfinding ==&lt;br /&gt;
&lt;br /&gt;
=== GetRoute ===&lt;br /&gt;
&lt;br /&gt;
The main entry point is GetRoute(startRegion, destRegion, workArray, groupID, ...).  It returns the total cost of the route and the route itself is stored in the temporary work array.  The steps in the route are accessed using GetArray(step).  For example to get the route from current to destination into the array route:&lt;br /&gt;
 &lt;br /&gt;
    int route[32];&lt;br /&gt;
    int i;&lt;br /&gt;
    cost = GetRoute(current, destination, 0, group);&lt;br /&gt;
    if (cost &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        for (i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
        {&lt;br /&gt;
            route[i] = GetArray(i);&lt;br /&gt;
            if (route[i] == -1)&lt;br /&gt;
            {&lt;br /&gt;
                i = 32; // done&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Internally, there are a number of callbacks during pathfinding so that the costs can be dynamically determined by scripts.  The sequence is something like this:&lt;br /&gt;
 &lt;br /&gt;
 /- GetRoute(startRegion, targetRegion, workArray, groupID, ...) BATTLESCRIPT command&lt;br /&gt;
 |    / | \&lt;br /&gt;
 |   v  v  v&lt;br /&gt;
 |  PathfindingData(region, neighbour, groupID, ...)                Map.BSF function&lt;br /&gt;
 |      |&lt;br /&gt;
 |      v&lt;br /&gt;
 |  SetPathfindingData(region, neighbour, cost, [speed])                  BATTLESCRIPT command&lt;br /&gt;
 |&lt;br /&gt;
 \-&amp;gt; GetRoute returns total cost&lt;br /&gt;
&lt;br /&gt;
PathfindingData is a function implemented in Map.BSF that tells the engine the cost of moving from one region to its neighbour them.  Simple calculations based on region and group properties can be used to determine the cost.  PathfindingData calls SetPathfindingData to return the cost and, optionally the speed used to take the step, if it is valid in the situation.  The base connection graph is determined internally based on the $REGION_CONNECTIONS attribute and assuming that legal movement costs are always &amp;gt; 0.  It is possible to pass additional parameters to the PathfindingData callback by adding more parameters to the function, and then padding them as additional parameters to GetRoute after the groupID.&lt;br /&gt;
&lt;br /&gt;
Internally, data is cached so that if you make consecutive calls to GetRoute for the same startRegion and groupID within the same frame, the result will be found much faster.  A loop with one group evaluating N destinations will be much faster than N groups evaluating one destination.&lt;br /&gt;
&lt;br /&gt;
If non-zero speeds are provided to SetPathfindingData, the engine will include the calculation of unused movement points not carried over between turns in the cost.  The speed expected is the speed used if a turn starts in 'region', pathfinding internally will determine whether to use that speed or continue with the previous speed.&lt;br /&gt;
&lt;br /&gt;
There is an alternate version of the command, GetRouteWithLimit, that takes a maximum cost which can be more efficient when long routes are not of interest.&lt;br /&gt;
&lt;br /&gt;
=== GetRouteEx ===&lt;br /&gt;
&lt;br /&gt;
GetRouteEx is a more advanced way to access pathfinding, GetRouteEx(sourceRegion, destRegion, [dynArrayHandle], [maxCost], [callback], [data...]).&lt;br /&gt;
&lt;br /&gt;
The primary difference is that the name of the callback function can be provided to GetRouteEx.  The first parameter to the callback function will always be the region ID that data is requested for, all additional integer parameters will be passed through from the GetRouteExcall to the callback.  Also, it uses a dynamic array for results (you can pass a dynamic array handle of 0 to get the cost of the route if you do not require the route itself).  Finally, it take a maximum cost like GetRouteWithLimit (or &amp;lt;= 0 if cost is unlimited).&lt;br /&gt;
&lt;br /&gt;
For example, to get the optimal path from startID to destID up to a cost of 12 using the same callback as GetRoute uses:&lt;br /&gt;
 handle = CreateDyamicArray();&lt;br /&gt;
 GetRouteEx(startID, destID, 12, handle, &amp;quot;PathfindingData&amp;quot;, groupID);&lt;br /&gt;
 ...&lt;br /&gt;
 DestroyDynamicArray(handle);&lt;br /&gt;
&lt;br /&gt;
To use a callback that uses different criteria or a different calculation, define another callback function:&lt;br /&gt;
 FUNCTION PathfindingDataByKind(regionID, neighbourID, kind, faction)&lt;br /&gt;
 {&lt;br /&gt;
     int cost;&lt;br /&gt;
     &lt;br /&gt;
     cost = myCost(neighbourID, kind, faction);&lt;br /&gt;
     SetPathfindingData(regionID, neighbourID, cost);&lt;br /&gt;
 }&lt;br /&gt;
And then provide the name and expected parameters to the search:&lt;br /&gt;
 GetRouteEx(startID, destID, 12, handle, &amp;quot;PathfindingDataByKind&amp;quot;, kind, factionID);&lt;br /&gt;
&lt;br /&gt;
If the callback name and parameters are omitted, the search will be done without script callbacks based on the Connections attribute of the regions with a fixed cost of 1 for each step.&lt;br /&gt;
&lt;br /&gt;
=== GetRegionsInRange ===&lt;br /&gt;
&lt;br /&gt;
Pathfinding can also be used to find a list of regions in range of another.  The entry point for this is GetRegionsInRange(sourceRegion, maxCost, dynArrayHandle, [callback], [data...]).&lt;br /&gt;
&lt;br /&gt;
The parameters have the same meaning as in GetRouteEx.  For example, to get all regions within a cost of 12 of startID using the same callback as GetRoute uses:&lt;br /&gt;
 handle = CreateDyamicArray();&lt;br /&gt;
 GetRegionsInRange(startID, 12, handle, &amp;quot;PathfindingData&amp;quot;, groupID);&lt;br /&gt;
 ...&lt;br /&gt;
 DestroyDynamicArray(handle);&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Scripting&amp;diff=509</id>
		<title>Empires Scripting</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Scripting&amp;diff=509"/>
		<updated>2019-07-08T20:03:17Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the general [[Scripting]] page for a description of the Archon scripting language.  See My Games\FieldOfGloryEmpires\AUTODOCS\BATTLESCRIPT.TXT for definitive script command descriptions relevant to Empires.&lt;br /&gt;
&lt;br /&gt;
Also output to the AUTODOCS folder is ARCHON.XML, a language definition compatible with Notepad++ (note that if the language definition is updated, the defined language must be removed and re-imported into Np++, it will not reload it automatically).&lt;br /&gt;
&lt;br /&gt;
== Pathfinding ==&lt;br /&gt;
&lt;br /&gt;
=== GetRoute ===&lt;br /&gt;
&lt;br /&gt;
The main entry point is GetRoute(startRegion, destRegion, workArray, groupID, ...).  It returns the total cost of the route and the route itself is stored in the temporary work array.  The steps in the route are accessed using GetArray(step).  For example to get the route from current to destination into the array route:&lt;br /&gt;
 &lt;br /&gt;
    int route[32];&lt;br /&gt;
    int i;&lt;br /&gt;
    cost = GetRoute(current, destination, 0, group);&lt;br /&gt;
    if (cost &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        for (i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
        {&lt;br /&gt;
            route[i] = GetArray(i);&lt;br /&gt;
            if (route[i] == -1)&lt;br /&gt;
            {&lt;br /&gt;
                i = 32; // done&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Internally, there are a number of callbacks during pathfinding so that the costs can be dynamically determined by scripts.  The sequence is something like this:&lt;br /&gt;
 &lt;br /&gt;
 /- GetRoute(startRegion, targetRegion, workArray, groupID, ...) BATTLESCRIPT command&lt;br /&gt;
 |    / | \&lt;br /&gt;
 |   v  v  v&lt;br /&gt;
 |  PathfindingData(region, neighbour, groupID, ...)                Map.BSF function&lt;br /&gt;
 |      |&lt;br /&gt;
 |      v&lt;br /&gt;
 |  SetPathfindingData(region, neighbour, cost, [speed])                  BATTLESCRIPT command&lt;br /&gt;
 |&lt;br /&gt;
 \-&amp;gt; GetRoute returns total cost&lt;br /&gt;
&lt;br /&gt;
PathfindingData is a function implemented in Map.BSF that tells the engine the cost of moving from one region to its neighbour them.  Simple calculations based on region and group properties can be used to determine the cost.  PathfindingData calls SetPathfindingData to return the cost and, optionally the speed used to take the step, if it is valid in the situation.  The base connection graph is determined internally based on the $REGION_CONNECTIONS attribute and assuming that legal movement costs are always &amp;gt; 0.  It is possible to pass additional parameters to the PathfindingData callback by adding more parameters to the function, and then padding them as additional parameters to GetRoute after the groupID.&lt;br /&gt;
&lt;br /&gt;
Internally, data is cached so that if you make consecutive calls to GetRoute for the same startRegion and groupID within the same frame, the result will be found much faster.  A loop with one group evaluating N destinations will be much faster than N groups evaluating one destination.&lt;br /&gt;
&lt;br /&gt;
If non-zero speeds are provided to SetPathfindingData, the engine will include the calculation of unused movement points not carried over between turns in the cost.  The speed expected is the speed used if a turn starts in 'region', pathfinding internally will determine whether to use that speed or continue with the previous speed.&lt;br /&gt;
&lt;br /&gt;
There is an alternate version of the command, GetRouteWithLimit, that takes a maximum cost which can be more efficient when long routes are not of interest.&lt;br /&gt;
&lt;br /&gt;
=== GetRouteEx ===&lt;br /&gt;
&lt;br /&gt;
GetRouteEx is a more advanced way to access pathfinding, GetRouteEx(sourceRegion, destRegion, [dynArrayHandle], [maxCost], [callback], [data...]).&lt;br /&gt;
&lt;br /&gt;
The primary difference is that the name of the callback function can be provided to GetRouteEx.  The first parameter to the callback function will always be the region ID that data is requested for, all additional integer parameters will be passed through from the GetRouteExcall to the callback.  Also, it uses a dynamic array for results (you can pass a dynamic array handle of 0 to get the cost of the route if you do not require the route itself).  Finally, it take a maximum cost like GetRouteWithLimit (or &amp;lt;= 0 if cost is unlimited).&lt;br /&gt;
&lt;br /&gt;
For example, to get the optimal path from startID to destID up to a cost of 12 using the same callback as GetRoute uses:&lt;br /&gt;
 handle = CreateDyamicArray();&lt;br /&gt;
 GetRouteEx(startID, destID, 12, handle, &amp;quot;PathfindingData&amp;quot;, groupID);&lt;br /&gt;
 ...&lt;br /&gt;
 DestroyDynamicArray(handle);&lt;br /&gt;
&lt;br /&gt;
To use a callback that uses different criteria or a different calculation, define another callback function:&lt;br /&gt;
 FUNCTION PathfindingDataByKind(regionID, neighbourID, kind, faction)&lt;br /&gt;
 {&lt;br /&gt;
     int cost;&lt;br /&gt;
     &lt;br /&gt;
     cost = myCost(neighbourID, kind, faction);&lt;br /&gt;
     SetPathfindingData(regionID, neighbourID, cost);&lt;br /&gt;
 }&lt;br /&gt;
And then provide the name and expected parameters to the search:&lt;br /&gt;
 GetRouteEx(startID, destID, 12, handle, &amp;quot;PathfindingDataByKind&amp;quot;, kind, factionID);&lt;br /&gt;
&lt;br /&gt;
If the callback name and parameters are omitted, the search will be done without script callbacks based on the Connections attribute of the regions with a fixed cost of 1 for each step.&lt;br /&gt;
&lt;br /&gt;
=== GetRegionsInRange ===&lt;br /&gt;
&lt;br /&gt;
Pathfinding can also be used to find a list of regions in range of another.  The entry point for this is GetRegionsInRange(sourceRegion, maxCost, dynArrayHandle, [callback], [data...]).&lt;br /&gt;
&lt;br /&gt;
The parameters have the same meaning as in GetRouteEx.  For example, to get all regions within a cost of 12 of startID using the same callback as GetRoute uses:&lt;br /&gt;
 handle = CreateDyamicArray();&lt;br /&gt;
 GetRegionsInRange(startID, 12, handle, &amp;quot;PathfindingData&amp;quot;, groupID);&lt;br /&gt;
 ...&lt;br /&gt;
 DestroyDynamicArray(handle);&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Scripting&amp;diff=508</id>
		<title>Empires Scripting</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Scripting&amp;diff=508"/>
		<updated>2019-07-08T18:43:52Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See the general [[Scripting]] page for a description of the Archon scripting language.  See My Games\FieldOfGloryEmpires\AUTODOCS\BATTLESCRIPT.TXT for definitive script command descriptions relevant to Empires.&lt;br /&gt;
&lt;br /&gt;
Also output to the AUTODOCS folder is ARCHON.XML, a language definition compatible with Notepad++ (note that if the language definition is updated, the defined language must be removed and re-imported into Np++, it will not reload it automatically).&lt;br /&gt;
&lt;br /&gt;
== Pathfinding ==&lt;br /&gt;
&lt;br /&gt;
=== GetRoute ===&lt;br /&gt;
&lt;br /&gt;
The main entry point is GetRoute(startRegion, destRegion, workArray, groupID, ...).  It returns the total cost of the route and the route itself is stored in the temporary work array.  The steps in the route are accessed using GetArray(step).  For example to get the route from current to destination into the array route:&lt;br /&gt;
 &lt;br /&gt;
    int route[32];&lt;br /&gt;
    int i;&lt;br /&gt;
    cost = GetRoute(current, destination, 0, group);&lt;br /&gt;
    if (cost &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        for (i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
        {&lt;br /&gt;
            route[i] = GetArray(i);&lt;br /&gt;
            if (route[i] == -1)&lt;br /&gt;
            {&lt;br /&gt;
                i = 32; // done&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Internally, there are a number of callbacks during pathfinding so that the costs can be dynamically determined by scripts.  The sequence is something like this:&lt;br /&gt;
 &lt;br /&gt;
 /- GetRoute(startRegion, targetRegion, workArray, groupID, ...) BATTLESCRIPT command&lt;br /&gt;
 |    / | \&lt;br /&gt;
 |   v  v  v&lt;br /&gt;
 |  PathfindingData(region, neighbour, groupID, ...)                Map.BSF function&lt;br /&gt;
 |      |&lt;br /&gt;
 |      v&lt;br /&gt;
 |  SetPathfindingData(region, neighbour, cost, [speed])                  BATTLESCRIPT command&lt;br /&gt;
 |&lt;br /&gt;
 \-&amp;gt; GetRoute returns total cost&lt;br /&gt;
&lt;br /&gt;
PathfindingData is a function implemented in Map.BSF that tells the engine the cost of moving from one region to its neighbour them.  Simple calculations based on region and group properties can be used to determine the cost.  PathfindingData calls SetPathfindingData to return the cost and, optionally the speed used to take the step, if it is valid in the situation.  The base connection graph is determined internally based on the $REGION_CONNECTIONS attribute and assuming that legal movement costs are always &amp;gt; 0.  It is possible to pass additional parameters to the PathfindingData callback by adding more parameters to the function, and then padding them as additional parameters to GetRoute after the groupID.&lt;br /&gt;
&lt;br /&gt;
Internally, data is cached so that if you make consecutive calls to GetRoute for the same startRegion and groupID within the same frame, the result will be found much faster.  A loop with one group evaluating N destinations will be much faster than N groups evaluating one destination.&lt;br /&gt;
&lt;br /&gt;
If non-zero speeds are provided to SetPathfindingData, the engine will include the calculation of unused movement points not carried over between turns in the cost.  The speed expected is the speed used if a turn starts in 'region', pathfinding internally will determine whether to use that speed or continue with the previous speed.&lt;br /&gt;
&lt;br /&gt;
There is an alternate version of the command, GetRouteWithLimit, that takes a maximum cost which can be more efficient when long routes are not of interest.&lt;br /&gt;
&lt;br /&gt;
=== GetRouteEx ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== GetRegionsInRange ===&lt;br /&gt;
&lt;br /&gt;
Pathfinding can also be used to find a list of regions in range of another.  The entry point for this is GetRegionsInRange(sourceRegion, maxCost, dynArrayHandle, [callback], [data...]).&lt;br /&gt;
&lt;br /&gt;
Similar to GetRoute, evaluating a GetRegionsInRange request will result in a number of calls to a callback function which must call SetPathfindingData to provide costs to the engine.  The difference is that the name of the callback function can be provided to GetRegionsInRange.  The first parameter to the callback function will always be the region ID that data is requested for, all additional integer parameters will be passed through from the GetRegionsInRange call to the callback.&lt;br /&gt;
&lt;br /&gt;
For example, to get all regions within a cost of 12 of startID using the same callback as GetRoute uses:&lt;br /&gt;
 handle = CreateDyamicArray();&lt;br /&gt;
 GetRegionsInRange(startID, 12, handle, &amp;quot;PathfindingData&amp;quot;, groupID);&lt;br /&gt;
 ...&lt;br /&gt;
 DestroyDynamicArray(handle);&lt;br /&gt;
&lt;br /&gt;
To use a callback that uses different criteria or a different calculation, define another callback function:&lt;br /&gt;
 FUNCTION PathfindingDataByKind(regionID, neighbourID, kind, faction)&lt;br /&gt;
 {&lt;br /&gt;
     int cost;&lt;br /&gt;
     &lt;br /&gt;
     cost = myCost(neighbourID, kind, faction);&lt;br /&gt;
     SetPathfindingData(regionID, neighbourID, cost);&lt;br /&gt;
 }&lt;br /&gt;
And then provide the name and expected parameters to the search:&lt;br /&gt;
 GetRegionsInRange(startID, 12, handle, &amp;quot;PathfindingDataByKind&amp;quot;, kind, factionID);&lt;br /&gt;
&lt;br /&gt;
If the callback name and parameters are omitted, the search will be done without script callbacks based on the Connections attribute of the regions with a fixed cost of 1 for each step.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Flavour_Specific_Documentation&amp;diff=507</id>
		<title>Flavour Specific Documentation</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Flavour_Specific_Documentation&amp;diff=507"/>
		<updated>2019-07-08T18:37:10Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Tile Turn Based Version]]&lt;br /&gt;
&lt;br /&gt;
[[Hex Turn Based Version|Steel Tigers Version]]&lt;br /&gt;
&lt;br /&gt;
[[Empires Version]]&lt;br /&gt;
&lt;br /&gt;
[[RTS Version]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=AEP_Version&amp;diff=506</id>
		<title>AEP Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=AEP_Version&amp;diff=506"/>
		<updated>2019-07-08T18:36:35Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Version to Empires Version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Empires Version]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=505</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=505"/>
		<updated>2019-07-08T18:36:35Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Andrewg moved page AEP Version to Empires Version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[AEP Scripting]]&lt;br /&gt;
* [[AEP Callbacks]]&lt;br /&gt;
* [[BattleBoard]]&lt;br /&gt;
* [[AEP Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;br /&gt;
* [[AEP Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=504</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=504"/>
		<updated>2019-06-10T17:57:20Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Sharing Mods */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select the scenario to package from the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=503</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=503"/>
		<updated>2019-06-10T17:56:54Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;br /&gt;
&lt;br /&gt;
== Sharing Mods ==&lt;br /&gt;
&lt;br /&gt;
As mods are self-contained scenarios, you can share a mod simply by packing and distributing your custom scenario's subfolder from your user folder, which is then placed on the equivalent location in another player's user folder.&lt;br /&gt;
&lt;br /&gt;
Empires also supports the CPF and LST files in the same format as some previous Slitherine games to make installation easier for other players.  To create a CPF file, select Editor, select your the list of custom scenarios, and then press the Create Campaign Package File (CPF) button.  The CPF will be saved to your user SCENARIOS folder.&lt;br /&gt;
&lt;br /&gt;
See http://www.slitherinebravo.net/GameWiki/doku.php?id=mod_older_hot#share_unofficial_user_scenarios_on_any_platform for more information.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=502</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=502"/>
		<updated>2019-06-05T23:57:39Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Advanced */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
If an existing modifier doesn't suit your unit, you can create a new modifier by copying MODIFIERS.CSV from the DATA folder of the game installation to the DATA folder of your custom scenario.  Then add a new modifier following the pattern of the existing modifiers.  You can now refer to this new modifier from your unit.&lt;br /&gt;
&lt;br /&gt;
Modifiers refer to effects to apply statistical bonuses or penalties.  These effects are defined in DATA/EFFECTS.CSV, so as above you can create a new effect by copying the shared EFFECTS.CSV to your scenario's DATA folder and creating a new effect.&lt;br /&gt;
&lt;br /&gt;
Many unit effects only apply in specific terrain categories (indicated if the effect terrains column is 1).  In that case, the modifier will specify the terrains as the fourth parameter associated with that effect, using a combination of 1: Open, 2: Forest, 4: Arid, 8: Rough, 16: Swampy, 32: Assault, 64: Coastal Water, 128: Open Water, 256: Steppe, 512: Mountainous.  For example:&lt;br /&gt;
&lt;br /&gt;
ID_MOD_UNIT_MOUNTAINMEN has multiple effects, effectID[0] is $MOD_EFFECT_MOVE_BONUS, which is means the first effect is a movement speed bonus.  params0[3] is 520, which is 512 + 8, indicating that this bonus applies in Mountainous and Rough terrain.  Referring to the terrain categories in DATA/TERRAINS.CSV, we see that the Mountainous category includes both Mountain and Alpine terrain types, and the Rough category includes Hills and Arid Hills.&lt;br /&gt;
&lt;br /&gt;
If you wish to create your own 'skin' for an existing unit model, you can add a new texture set for the unit by using an existing texture set as a template and following the naming of the texture exactly (although you may use a TGA file with the .tga extension instead of a DDS file) in the correct location for the next texture set within your scenario.  For example, the Hoplite_vet_arm model uses the Hoplite_Vet_Diffuse.dds texture.  The highest numbered texture set defined in the game is DATA\ASSETS\UNITS\Hoplite_Vet_Diffuse.dds, texture set 5.  If you create a new texture set and place it within your scenario at DATA\ASSETS\UNITS\texture6\Hoplite_Vet_Arm_Diffuse.tga, you can then refer to Asset Hoplite_Vet_Arm and TextureSet 6 in UNITVISUALS.CSV and it will use your new texture set.  If specular and normal maps aren't provided for a texture set, the versions from set 0 for that model will be used.&lt;br /&gt;
&lt;br /&gt;
If you have a new 3D model in the S4F format, you will need to add a row in a copy of DATA/SQUADS.CSV that refers to that model before you can use it in your UNITVISUALS.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=501</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=501"/>
		<updated>2019-06-05T22:02:43Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Adding Units */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
* UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
* UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
* UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=500</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=500"/>
		<updated>2019-06-05T21:57:25Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Adding Units */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
Next, in your UNITVISUALS.CSV, you will need to have an entry for added units.  Each unit type must have at least one 'garment' specified:&lt;br /&gt;
* Unit - A reference to the Alias of the unit in UNITS.CSV.&lt;br /&gt;
* Garment - Allows the same type of unit to have different appearances in different factions.  This value is either $GARMENT_DEFAULT if it is the default appearance, or a match to the Garment entry for a faction in DATA\FACTIONS.CSV.&lt;br /&gt;
* Asset - Specifies the 3D model used for this unit, this is a reference to a row in DATA\SQUADS.CSV (note this is not prefixed with a $ as most references are).  Typically, this corresponds to a model in DATA\ASSETS\UNITS in S4F format which is a proprietary Slitherine model and animation format.&lt;br /&gt;
* TextureSet - Used to control which color and pattern variation to use for this unit.  Unit models typically have multiple sets of possible textures, you can preview these by viewing the 'diffuse' textures in DATA\ASSETS\UNITS.  Texture set 0 is found in the root of that folder.  Other texture sets are found in the texture# subfolders.&lt;br /&gt;
* TextureVariant - Within each texture set are up to 4 variants (cavalry and other complex units may only have 2 or 1 variants per set).  0 is the top left variant, 1 is the top right, 2 is the bottom left, and 3 is the bottom right.  For example, TextureSet 1, Texture Variant 3 of the african_spearmen, uses the lower right quadrant of DATA\ASSETS\UNITS\texture1\African_Spearman_Diffuse.dds when drawing the unit.&lt;br /&gt;
&lt;br /&gt;
Finally, new units will need to be added to the pool of factions that they are available to.  In your FACTIONS.CSV, update:&lt;br /&gt;
UnitsAge1 - a | separated list of unit references for units available to the faction in the lowest category of government (Horde, Tyranny, Kingdom, Oligarchy, or Sect).&lt;br /&gt;
UnitsAge2 - a | separated list of unit references for units available to the faction in the second category of government (Tribe, City State, Monarchy, Republic, or Hierocracy).&lt;br /&gt;
UnitsAge3 - a | separated list of unit references for units available to the faction in the third category of government (Confederation, Commonwealth, Empire, Federation, or Theocracy).&lt;br /&gt;
&lt;br /&gt;
You should now be able to start your scenario and have your new or modified units available.&lt;br /&gt;
&lt;br /&gt;
=== Advanced ===&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=499</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=499"/>
		<updated>2019-06-05T21:14:54Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Adding Units */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
* ProgRate - The experience points required to reach Experience Level 1.&lt;br /&gt;
* InitialXPLevel - The base initial Experience Level for this unit.&lt;br /&gt;
* Garrison_Category - For units which can be recruited as automatic garrisons, this must correspond to one of the Garrison_Category entries of the structure which provides the garrison, in DATA\STRUCTURES.CSV.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=498</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=498"/>
		<updated>2019-06-05T21:01:19Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Adding Units */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] - Modifiers for this unit, a reference to a row in DATA\MODIFIERS.CSV.&lt;br /&gt;
* NotBuildable - If set to 1, this unit will not be recruitable normally (ex. units that only appear in garrisons).&lt;br /&gt;
* BuildPointsCost, ManpowerCost, MoneyCost, MetalCost - Equipment, Manpower, Money and Metal costs to recruit.&lt;br /&gt;
* ManpowerUpkeep, MoneyUpkeep, MetalUpkeep - Manpower, Money, and Metal maintenance costs.&lt;br /&gt;
* MoneyInflationCost - The increase in Money cost per unit of this type.&lt;br /&gt;
* ShipyardNeed - The level of shipyard needed in a region to recruit the unit.&lt;br /&gt;
* Recruit_Weight - A weight given to this unit when doing randomized unit recruitment.&lt;br /&gt;
* RecruitArea - Optionally limits recruitment of this unit to a specific group or regions, a reference to a row in DATA\AREAS.CSV&lt;br /&gt;
* RequiredStructures - If a structure or | separated list of structures is given, the unit can only be recruited in regions where at least one of the structures is present.  The structures are references to rows in DATA\STRUCTURES.CSV&lt;br /&gt;
* NationalUnique - If non-zero, a faction cannot recruit the unit if it already has one.&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=497</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=497"/>
		<updated>2019-06-05T20:36:53Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Adding Units */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Before starting, if your custom scenario doesn't already contain these files, copy them from the game install folder (as above, do not edit them directly in your game installation):&lt;br /&gt;
* DATA\UNITS.CSV&lt;br /&gt;
* DATA\UNITVISUALS.CSV&lt;br /&gt;
* DATA\FACTIONS.CSV&lt;br /&gt;
&lt;br /&gt;
To add a new unit, start by adding a new row to your UNITS.CSV, or copying the row describing a similar unit.  You must fill in these fields:&lt;br /&gt;
* ID - This must be a unique number greater than zero, start with something well beyond the range of values in the standard unit list to avoid conflicts later, ex 10000.&lt;br /&gt;
* Alias - This must be a unique and descriptive string starting with &amp;quot;ID_UNI_&amp;quot; that you will use to identify this unit later in other data files.&lt;br /&gt;
* Name - This is a reference to the name used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_NAME_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
* Text - This is a reference to the description used for this unit type. Add a new, unique string id in this table (by convention, starting with IDS_UNIT_TEXT_ and ending with the unique portion of the Alias) and then define a new string with this id in your scenario's TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
To complete your new unit, or if you are simply modifying an existing unit, also set these fields:&lt;br /&gt;
* FOG2_Name - This is the type of unit this will be exported as when a battle is exported to Field of Glory 2.  This must match a value in the Name column of Field of Glory II\Data\Squads.csv, or copy a value from a similar unit if you are unsure.&lt;br /&gt;
* FOG2_QualityMOD - When exported to Field of Glory 2, this is the base quality of a unit relative to the type given above, as a percentage.  Set this to 100 if you are unsure.&lt;br /&gt;
* AGEOD_Cost - When exported to Field of Glory 2, this is used in the calculation of how many units are created in FOG2 for each Empires unit.&lt;br /&gt;
* Family - The category of this unit, possibly values are: $famInfantry, $famHvyInfantry, $famArcher, $famSkirmisher, $famLtCavalry, $famSkirmisherCavalry, $famCavalry, $famHvyCavalry, $famHvyBeast, $famSiege, $famLtWarship, $famWarship, $famHvyWarship, $famTransport&lt;br /&gt;
* EvolveFamily - If non-zero - if this unit becomes obsolete it can be replaced by another unit with the same value, or another unit with the same value becomes obsolete it can be replaced by this unit.&lt;br /&gt;
* EvolvePriority - If an EvolveFamily is set, it is used to pick the best unit to evolve an obsolete unit to.&lt;br /&gt;
* UpdgradeNext - Used in Event/Decision driven unit upgrades.&lt;br /&gt;
* MoveSpeed - The movement speed of the unit.&lt;br /&gt;
* Hits - The maximum number of Hits of the unit.&lt;br /&gt;
* Effectiveness - The maximum Effectiveness value of the unit.&lt;br /&gt;
* Attack - The base Attack value of the unit.&lt;br /&gt;
* Defense - The base Defense value of the unit.&lt;br /&gt;
* IsSupport - Does the unit behave as a support unit in combat.&lt;br /&gt;
* DistanceToCenter - Low values will cause a unit to be deployed near the center of combat, high values will deploy the unit near the flanks.&lt;br /&gt;
* AssaultDistanceToCenter - As DistanceToCenter, but used during assaults.&lt;br /&gt;
* Siege - The Siege value of the unit.&lt;br /&gt;
* SiegeResist - The Siege Resist value of the unit.&lt;br /&gt;
* SupplyUsage - The amount of supply consumed by the unit per turn (1 food typically provides 5 supply, before bonuses and penalties).&lt;br /&gt;
* AttackingRange - During the ranged attack phase of combat, can the unit target the opponent front line (0), support line (1), or reserves (2).&lt;br /&gt;
* RangedAttack - The Ranged Attack score of the unit, or 0 for units without a ranged attack.&lt;br /&gt;
* RangedDefense - The Ranged Defense score of the unit.&lt;br /&gt;
* RangedMaxDamages - The limit of Effectiveness damage done by the unit during the ranged attack phase.&lt;br /&gt;
* FlankingModifier - A bonus used when calculating flanking or pursuit damage inflicted by this unit.&lt;br /&gt;
* Modifier[0 - 3] -&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=496</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=496"/>
		<updated>2019-05-29T21:27:41Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Modding Guide */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
│   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
* Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Many files not specifically covered elsewhere can still be overridden in a modified scenario.  Generally, if a file is found anywhere in the Data folder of the game installation, you can place a modified version of that file in the same relative location of the DATA folder of your modified scenario and your scenario will use that instead.&lt;br /&gt;
&lt;br /&gt;
== The Editor ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=495</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=495"/>
		<updated>2019-05-29T21:10:39Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Changing the Scenario Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
|   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
│&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Three files of particular interest when changing the setup of the scenario are found in the DATA folder - SETUP.csv, SETUP_FACTIONS.csv, and REGIONS.csv.  These files are semi-colon separated CSVs and can be opened and edited in most spreadsheet software (ex Excel, OpenOffice), just be sure to save them in the same format.&lt;br /&gt;
&lt;br /&gt;
=== SETUP_FACTIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines which factions are available in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
=== REGIONS.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file specifies the basic properties of each region on the map.&lt;br /&gt;
* Alias: This is used as a reference to this region elsewhere.  It is not recommended that you change this column, as it is used to associate this region with an area in the map used by this scenario.&lt;br /&gt;
* Name: This is a reference to the name used for this region.  To edit the name, do not change the reference itself, but create a new entry with this id in the TEXT1.TXT file you edited above.&lt;br /&gt;
* Terrain: This is the terrain type of this region.  For a list of valid terrain types, see DATA\TERRAINS.CSV, although some terrain types are not valid to assign directly to a region.  Note that the reference must begin with $.  This is generally the case when referring to an Alias from another CSV.&lt;br /&gt;
Res[0], Res[1], Res[2], Res[3]: These are the natural resources present in the region.  For a list of possible resources, see DATA\RESOURCES.CSV.&lt;br /&gt;
* Disabled: This controls which regions defined in the map are included in the scenario.&lt;br /&gt;
* Faction: This is the faction which initially owns this region (see SETUP_FACTIONS.CSV)&lt;br /&gt;
* CitizensID[0], CitizensAmount[0]: CitizensID[0] is the ethnicity of a the citizens to add, see DATA\ETHNICS.CSV for a list of possible ethnicities. CitizensAmount[0] is the number of citizens of the given ethnicity to add.  Citizens will initially be distributed among the four possible jobs.  To add citizens of multiple ethnicities, use CitizensID[1-3] and CitizensAmount[1-3].&lt;br /&gt;
* SlavesID[0], SlavesAmount[0]: add slaves to the region, similar to citizens above, although they will only be initially assigned to Agriculture or Infrastructure.&lt;br /&gt;
* City_Name: This is a reference to the name of the city in this region.  As with the region name, you can override the name by adding a new entry to your TEXT1.TXT file.&lt;br /&gt;
&lt;br /&gt;
=== SETUP.CSV ===&lt;br /&gt;
&lt;br /&gt;
This file defines the initial placement of structures and groups (armies and navies) in your scenario.&lt;br /&gt;
&lt;br /&gt;
Coming soon&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=494</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=494"/>
		<updated>2019-05-29T20:03:53Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* Modding Guide */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
|   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
│&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;br /&gt;
&lt;br /&gt;
== Changing the Scenario Setup ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Units == &lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Structures ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Adding Events ==&lt;br /&gt;
&lt;br /&gt;
Coming soon?&lt;br /&gt;
&lt;br /&gt;
== Advanced Modding ==&lt;br /&gt;
&lt;br /&gt;
Coming soon??&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=493</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=493"/>
		<updated>2019-05-29T20:00:41Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Create a Scenario ==&lt;br /&gt;
&lt;br /&gt;
Empires currently only support mods by the creation of a new, modified scenario.  The quickest way to create a new scenario and get started modding is to copy an existing scenario.  For example, to start with the grand campaign, browse to the Scenarios folder in your game install folder (ex. C:\Program Files (x86)\Slitherine\Field of Glory Empires\Scenarios).  Copy the d310BCGrandCampaign folder into the SCENARIOS folder of your user folder (ex Documents\My Games\FieldOfGloryEmpires\SCENARIOS).  Rename the pasted folder to something new (it is recommended the new folder name not contain spaces).  You should also make sure this new folder and its contents are not Read-Only. Inside this folder, you should see a number of files:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;MYSCENARIO&lt;br /&gt;
│   SCENARIO.BSF&lt;br /&gt;
│   TEXT1.TXT&lt;br /&gt;
│   TEXT1_FRE.TXT&lt;br /&gt;
│   TEXT1_GER.TXT&lt;br /&gt;
|   TEXT1_SPA.TXT&lt;br /&gt;
│   SCENARIO.TXT&lt;br /&gt;
│&lt;br /&gt;
├───DATA&lt;br /&gt;
│   │   SETUP.csv&lt;br /&gt;
│   │   SETUP_FACTIONS.csv&lt;br /&gt;
│   │   REGIONS.csv&lt;br /&gt;
│   │   SETUP_GROUPS.csv&lt;br /&gt;
│   └───SCRIPTS&lt;br /&gt;
│           Events_Plugin.BSF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
A good place to start would be to open TEXT1.TXT in a text editor.  Here you can give your mod a unique name, description, and starting message.  See [[Modding#Custom_Text]] for details on modifying string files in the Archon engine.  TEXT1_FRE.TXT, TEXT1_GER.TXT, and TEXT1_SPA.TXT contain the translations of the strings in TEXT1.TXT.  If you do not plan to translate your mod into other languages, you should just remove these three files and the strings entered in TEXT1.TXT will be used for all languages.&lt;br /&gt;
&lt;br /&gt;
SCENARIO.BSF is another place you can make some quick edits to you scenario.  Refer to [[Scripting]] for a description of the Archon scripting language.  The InitScenario function near the beginning of this file sets up a number of parameters for your scenario, try changing gTurnInfos.dateFirstTurn to adjust the starting date for your mod.&lt;br /&gt;
&lt;br /&gt;
If you start the game and select Scenarios, your modified scenario should now appear near the bottom of the list and be selectable for play.&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=492</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=492"/>
		<updated>2019-05-28T23:50:10Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[AEP Scripting]]&lt;br /&gt;
* [[AEP Callbacks]]&lt;br /&gt;
* [[BattleBoard]]&lt;br /&gt;
* [[AEP Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;br /&gt;
* [[AEP Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=491</id>
		<title>Empires Modding</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Modding&amp;diff=491"/>
		<updated>2019-05-28T20:54:51Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Created page with &amp;quot;= Modding Guide =  == Getting Started ==  Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Modding Guide =&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Empires saves user files in your Documents\My Games\FieldOfGloryEmpires folder, which will be referred to as your 'user' folder.  In addition to saved games, logs, and options files, this is where user created mods are located.  Editing files directly in the game install folder (ex C:\Program Files (x86)\Slitherine\Field of Glory Empires) is NOT recommended, doing so may prevent multiplayer games from working correctly and interfere with game updates.&lt;br /&gt;
&lt;br /&gt;
Before you begin modding, you may wish to open the USER.TXT file in your user folder and the following line to enable additional debugging tools:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;DEBUGMODE 1&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=490</id>
		<title>Empires Version</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=Empires_Version&amp;diff=490"/>
		<updated>2019-05-28T20:44:45Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[AEP Scripting]]&lt;br /&gt;
* [[AEP Callbacks]]&lt;br /&gt;
* [[BattleBoard]]&lt;br /&gt;
* [[AEP Terrain]]&lt;br /&gt;
* [[AEP Hotkeys]]&lt;br /&gt;
* [[AEP_Modding]]&lt;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=482</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=482"/>
		<updated>2019-01-23T17:42:24Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: Corrected documentation of BARSIZE tag, no change to engine behaviour.&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. Valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12&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;
&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.&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;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&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;
== 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;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=480</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=480"/>
		<updated>2018-12-13T21:01:39Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* BARCHART */&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. Valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12&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;
&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&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 32.&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;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&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;
== 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;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=476</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=476"/>
		<updated>2018-11-21T00:51:40Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* 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;
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. Valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12&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;
&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&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 32.&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;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&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;
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;&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;&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;
== 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;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
	<entry>
		<id>https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=471</id>
		<title>UI</title>
		<link rel="alternate" type="text/html" href="https://archonwiki.slitherine.com/index.php?title=UI&amp;diff=471"/>
		<updated>2018-09-29T01:00:06Z</updated>

		<summary type="html">&lt;p&gt;Andrewg: /* 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;
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. Valid key values are A-Z and 0-9 as well as TAB, SPACE, RETURN, BACKSPACE, ESC, LEFT, RIGHT, UP, DOWN, F1 - F12&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;
&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&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 32.&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, items and the string referenced by headerID are &lt;br /&gt;
                   treated as tab (\t) delimited rows, behaviour may also be activated or updated 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)&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;
Defines the display of the listbox item text.&amp;lt;/nowiki&amp;gt;&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.  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 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.  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 colours are blended with the image colour, with zero meaning that the image colours are fully modulated with the side colour, 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 exists, the system will display that section of the drawn image with no colouration or other changes.  These are 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 coordinates using the RegionMapGetX/Y functions).  DATA can be used for preset data on each area to be used in the script.  There can be up to 4 data elements in the list.&lt;br /&gt;
NOTE: While there are both Get and Set functions (RegionMapGetData/RegionMapSetData) it is important to note that this region data is NOT saved as part of a save game and so the Set function should only be used for data which 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;
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;&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;&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;
== 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;/div&gt;</summary>
		<author><name>Andrewg</name></author>
	</entry>
</feed>