Battle Hierarchy
References must be obtained to objects in battle - chiefly unit
objects - in order to query and direct the course of events in a scripted battle. These script references are obtained through a hierarchy, accessed from the battle
/battle_manager
objects.
Relevant in Battle |
In practise, the objects in the hierarchy described on this page are rarely created or used directly in battle scripts. Use of the frameworks provided by the script_unit
and generated_battle
libraries means that minimal direct references to the objects described on this page need to be created in battle scripts. Nevertheless, it is important to know about the battle object hierarchy and how it is laid out as it underpins all the script systems built on top of it.
The table below shows the list of object types found within the hierarchy, and how they are sourced from the battle
object and then from one another:
Object | Sample Script | Comments |
| alliances = bm:alliances() | The alliances object is a list of all the alliances present on the battlefield. An alliance is one or more armies on the battlefield that are fighting together. The alliances object may be retrieved by calling battle:alliances . |
| alliance = alliances:item(1) | Each alliance object represents an alliance participating in the battle. Individual alliance objects are retrieved from an alliances object with the alliances:item method. The index of an battle:alliances object is 1-based, so supplying 1 as an argument to alliances:item would return the first alliance, which is always the attacker in the battle.In all circumstances (at time of writing) there are exactly two alliance objects in the alliances list. |
| armies = alliance:armies() | An armies object is a list of individual army objects that belong to a particular alliance. |
| army = armies:item(1) | An army object represents a logical army on the battlefield, which is a collection of units of the same faction fighting together under the same controlling entity (either the player or the AI). A army object is retrieved from an armies list object by calling armies:item . |
| units = army:units() | A units object is a list of individual unit objects that belong to a specific army in the battle. It may be retrieved by calling army:units . |
| unit = units:item(1) | Each unit object represents an individual unit on the battlefield. Unit objects may be retrieved from a units list object by calling units:item . |
This diagram shows the setup above in pictoral form:
Traditional scripted battles tend to be directed at the unit level, so the interfaces to each unit
object (and the associated unitcontroller
objects - see further down this page) are the most useful interfaces of those in the hierarchy given above.
The partial example given below shows script creating handles to battle objects in a battle with two armies in each alliance. The two alliances are named alliance_a
and alliance_b
:
bm = battle_manager:new(empire_battle:new())
alliances = bm:alliances()
-- set up alliance_a objects
alliance_a = alliances:item(1)
armies_a = alliance_a:armies()
-- set up alliance_b objects
alliance_b = alliances:item(2)
armies_b = alliance_b:armies()
-- set up alliance_a army objects
army_a1 = armies_a:item(1)
units_a1 = army_a1:units()
army_a2 = armies_a:item(2)
units_a2 = army_a2:units()
-- set up alliance b army objects
army_b1 = armies_b:item(1)
units_b1 = army_b1:units()
army_b2 = armies_b:item(2)
units_b2 = army_b2:units()
-- set up army a1 units
unit_a1_1 = units_a1:item(1)
unit_a1_2 = units_a1:item(2)
unit_a1_3 = units_a1:item(3)
-- etc
-- set up army a2 units
-- set up army b1 units
-- set up army b2 units
It is not often necessary to get and retain handles to all objects in the hierarchy. The partial example given below is the same as the first but without handles created to list objects:
bm = battle_manager:new(empire_battle:new())
alliances = bm:alliances()
-- set up alliance objects
alliance_a = bm:alliances():item(1)
alliance_b = bm:alliances():item(2)
-- set up army objects
army_a1 = alliance_a:armies():item(1)
army_a2 = alliance_a:armies():item(2)
army_b1 = alliance_b:armies():item(1)
army_b2 = alliance_b:armies():item(2)
-- set up army a1 units
unit_a1_1 = army_a1:units():item(1)
unit_a1_2 = army_a1:units():item(2)
unit_a1_3 = army_a1:units():item(3)
-- etc
-- set up army a2 units
-- set up army b1 units
-- set up army b2 units
Each container object type provided by the battle hierarchy - alliances
, armies
and units
- provides the same interface and operates in the same way.
- Each contains a list of elements that belong to the parent object -
alliance
,army
andunit
objects respectively. - Elements may be retrieved in each case by calling the member function
item()
and supplying a numeric index value as a single argument. This index in each case is 1-based - the first element is retrieved with an index value of 1.
second_army = armies:army(2)
- The number of elements in a container object is returned by the
count()
member function.
num_units = units:count()
unit
objects provide a variety of methods that may be called to determine information about the unit they represent. To modify the state of a unit, however - to give it orders - a unitcontroller
must be created that acts upon the unit.
The army
code interface provides the army:create_unit_controller
for creating a unitcontroller and then attaching it to a unit:
uc_a1_1 = army_a1:create_unit_controller()
uc_a1_1:add_units(unit_a1_1)
The script libraries provide some helper functions for Unitcontroller Creation
. Furthermore, use of the script_unit
or generated_battle
frameworks negate the need for explicit unitcontroller creation - it is strongly recommended that these are used.
In practice, the full battle hierarchy and the traditional method of creating a unitcontroller are seldom used in the forms given above. A shorthand method of creating unit
and unitcontroller
objects together is supplied by the script_unit
library. In a full scripted battle it is highly recommended to set up handles to script_unit
objects instead of manually creating unit
and unitcontroller
objects. The partial example script given below is the same as those shown above, but with script_unit
objects declared in place of unit
objects.
bm = battle_manager:new(empire_battle:new())
alliances = bm:alliances()
-- set up alliance objects
alliance_a = bm:alliances():item(1)
alliance_b = bm:alliances():item(2)
-- set up army objects
army_a1 = alliance_a:armies():item(1)
army_a2 = alliance_a:armies():item(2)
army_b1 = alliance_b:armies():item(1)
army_b2 = alliance_b:armies():item(2)
-- set up army a1 units
sunit_a1_1 = scriptunit:new(army_a1, 1)
sunit_a1_2 = scriptunit:new(army_a1, 2)
sunit_a1_3 = scriptunit:new(army_a1, 3)
-- etc
-- set up army a2 units
-- set up army b1 units
-- set up army b2 units
Each script_unit
object contains a reference to a unit
object, as well as a unitcontroller
object set up to act upon that unit. These may be accessed at the unit
and uc
elements within the scriptunit (which is a lua table
) as follows:
unit_a1_1 = sunit_a1_1.unit
uc_a1_1 = sunit_a1_1.uc
The script_unit
packages a unit
and unitcontroller
together, as well as providing a suite of other functionality - see the script_unit
page for more information.
The generated_battle
system, if used, automatically sets up handles for armies and units in a battle. The partial example given below is the same as those shown above but set up using the generated_battle
system. No handles to individual unit
or script_unit
objects are explicitly created in this case as battles are co-ordinated and orders are given at the army level. This makes generated battle scripts easier to create and work with, at the expense of the fine unit-level control offered when creating a fully-scripted battle.
bm = battle_manager:new(empire_battle:new())
-- set up generated battle object
gb = generated_battle:new()
ga_a1 = gb:get_army(1, 1)
ga_a2 = gb:get_army(1, 2)
ga_b1 = gb:get_army(2, 1)
ga_b2 = gb:get_army(2, 2)
Note that it is still possible to get handles to individual units in the generated battle system, but if this is necessary it may be worth considering creating a full scripted battle instead.