Skip to content

Skirmish — armies and scenarios#

Summary#

Skirmish armies come from two layers:

  1. Embedded EXE tables — scenario indices, NPC nobles, map parameters, faction color pairs (GoG Lords2.exe VAs below).
  2. External TROOPS*.ENG / battles.eng — unit counts per preset and scenario display names, parsed at runtime into DAT_00516ac0 and name buffers.

Regenerate EXE tables:

python3 tools/ghidra/dump_skirmish_tables.py gog/Lords2.exe

Confidence: confirmed for EXE tables (dump script); likely for TROOPS*.ENG layout (inferred from FUN_0042ac0c parser).


Preset row indexing#

Battle types index into a flat preset row array via DAT_004d49b8:

Battle type Base row Count
0 — field A 0 10
1 — field B 10 10
2 — siege 20 15
3 — custom 35 20

Formula: preset_row = *(int*)(0x004D49B8 + battle_type*4) + scenario_index

Used by FUN_0042bf46, FUN_0042ba40, and NPC lookup.


NPC noble per scenario#

Table @ 0x004D4BC8 (GoG): culture_row per preset row → L2.ENG group 7 name. See nobles/README.md.

Field A (type 0, rows 0–9)#

Sc Noble
0 Baron
1 Knight
2 Countess
3 Bishop
4 Knight
5 Countess
6 Bishop
7 Baron
8 Knight
9 Countess

Field B (type 1, rows 10–19)#

Sc Noble
0 Baron
1 Knight
2 Countess
3 Bishop
4 Bishop
5 Countess
6 Baron
7 Knight
8 Bishop
9 Knight

Siege (type 2, rows 20–34)#

Sc Noble
0 Countess
1 Baron
2 Bishop
3 Knight
4 Knight
5 Countess
6 Bishop
7 Baron
8 Baron
9 Countess
10 Knight
11 Countess
12 Baron
13 Baron
14 Knight

Custom (type 3, rows 35–54)#

Sc Noble
0 Countess
1 Bishop
2 Baron
3 Countess
4 Knight
5 Bishop
6 Baron
7 Countess
8 Knight
9 Knight
10 Countess
11 Baron
12 Bishop
13 Knight
14 Countess
15 Baron
16 Countess
17 Knight
18 Knight
19 Countess

Faction color pairs#

@ 0x004D4CA8: when SP assigns NPC colors, if human faction color equals color_a, NPC gets color_b, else color_a.

culture_row color_a color_b
1 Knight 2 4
2 Baron 1 5
3 Countess 5 1
4 Bishop 4 2

Siege map IDs#

@ 0x004D4B58: DAT_0057c910 for siege scenarios (type 2).

Scenario map_id
0–3 0
4–14 1

Map parameter tables#

Each DAT_0053f258 slot (0–7, wraps after 8 battles) selects a 0x20-byte row loaded by lotr2_combat_init_battle_ui.

Preset table @ 0x004D8E18#

Slot map_id field_04 p08 p0c p10 p14 p18 p1c
0 17 0 5000 1 1 1 0 1
1 12 0 2500 1 1 1 0 2
2 2 1 5000 2 1 1 0 3
3 5 1 2500 3 0 1 0 4
4 0 2 5000 4 2 1 0 4
5 3 2 2500 4 1 1 0 4
6 7 2 1000 5 0 1 0 4
7 4 2 1000 5 0 1 0 4

Fields map to globals: DAT_0053f034, DAT_0053f23c, DAT_0053f278, DAT_0053f280, DAT_0053f27c, DAT_0053f270, DAT_0053f274, DAT_0053f268.

Custom table @ 0x004D8F58 (when DAT_0053f640 == 1)#

Slot map_id field_04 p08 p0c p10 p14 p18 p1c
0 0 0 0 0 0 0 0 4
1 0 0 0 0 0 0 0 4
2 52 2 5000 2 1 1 0 1
3 53 2 2500 3 0 1 0 1
4 45 2 2500 4 2 1 0 2
5 44 2 2500 4 1 1 0 3
6 41 2 1000 5 0 1 0 4
7 42 2 1000 5 0 1 0 4

Unit counts (TROOPS*.ENG)#

FUN_0042ac0c loads:

Session File Purpose
SP, local side troops2.eng Presets when local player attacks
SP, NPC side troops3.eng Presets when NPC attacks
MP troops.eng Both sides

Format (inferred): * delimits presets; first number after * is capacity cap (stored @ DAT_0051fae0 + preset*4); following digits are 11 unit types × layout dimensions:

  • 0x23 (35) preset rows max
  • Stride 0xdc bytes per preset in DAT_00516ac0
  • 5 faction-color rows × 2 sides × 11 unit types (types 0–10)
  • Sub-offset 0x16 per color, 0x6e per side

Counts copied into army record DAT_0052f21c (+0x1a4 stride) by FUN_0042bf46, indexed by:

base = DAT_004d49b8[battle_type] + scenario_index
offset = base * 0xdc + faction_color * 0x16 + side * 0x6e

Siege types use 7 unit columns in UI vs 11 for field (FUN_0042130f).

Clone requirement: ship or parse the three TROOPS*.ENG files from the game asset directory; they are not in this repository.


Scenario names (battles.eng)#

Loaded once; FUN_0042ab15(index*3) seeks the nth null-terminated string for the scenario list. Custom maps use the editable DAT_0053f5fc buffer instead.


Army record layout (skirmish battle)#

FUN_0042ba40 / FUN_0042bf46 fill two army slots:

Field Global Notes
Attacker army slot DAT_00568210 Usually 1
Defender army slot DAT_00568218 Usually 2
Attacker player DAT_00553efc 1 or 2
Defender player DAT_00553f34 2 or 1
Human slot lotr2_game_local_player_slot
Opponent slot DAT_0056d5cc 1 or 2

Evidence#

Item GoG VA
Preset bases 0x004D49B8
NPC nobles 0x004D4BC8
Color pairs 0x004D4CA8
Siege map IDs 0x004D4B58
Map preset rows 0x004D8E18
Map custom rows 0x004D8F58
Runtime unit block DAT_00516ac0

Dump tool: tools/ghidra/dump_skirmish_tables.py