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 loaded in battle
Back to top

A Note on Practical Use

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.

Back to top

A First Look

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:

ObjectSample ScriptComments
alliancesalliances = 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.
alliancealliance = 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.
armiesarmies = alliance:armies()An armies object is a list of individual army objects that belong to a particular alliance.
armyarmy = 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.
unitsunits = 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.
unitunit = 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:

battle hierarchy

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.

Back to top

Example Scripts

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

Back to top

Container Interfaces

Each container object type provided by the battle hierarchy - alliances, armies and units - provides the same interface and operates in the same way.

  1. Each contains a list of elements that belong to the parent object - alliance, army and unit objects respectively.
  2. 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)
  3. The number of elements in a container object is returned by the count() member function.

    num_units = units:count()

Back to top

Units and Unitcontrollers

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.

Back to top

Using Scriptunits

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.

Back to top

Setting Up a Generated Battle

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.

Last updated 25/08/2021 12:07:50