Skip to content

lotr2 unit and castle defense stat tables#

Static combat data from LORDS2.EXE .data. Regenerate with:

python3 tools/ghidra/dump_combat_tables.py
  • Numeric values: confirmed (binary dump + code cross-ref)
  • Unit / tile names: likely (code behavior + manual; confirm from l2.eng)

See also: lotr2_battle_figure.md, lotr2_battle_tile.md, lotr2_projectile.md, combat MODULE.


Casualty model (all units)#

Every soldier in a stack uses a 100-point damage accumulator (damage_acc). When accumulator exceeds 99, head_count decrements by 1 and 100 is subtracted. There is no per-type armor table.

Counter-attacks (infantry only) add counter_atk_damage to the attacker's pool on retaliation.


Melee attack damage (0x004f4c18)#

11 unit types × 4 uint16 tiers. Tier selected from head_count vs formation thresholds (0x004f4b28, map-size row DAT_005814f4).

Lookup: lotr2_combat_update_attack_damage // was thunk_FUN_00492cb1 @ 0x00492cb1

Unit ID Tier 0 Tier 1 Tier 2 Tier 3
Peasant 0 5 4 3 2
Archer 1 5 4 3 2
Swordsman 2 15 12 10 6
Maceman 3 15 12 10 6
Pikesman 4 10 8 6 5
Crossbowman 5 5 4 3 2
Knight 6 20 15 11 6
Catapult 7 0 0 0 0
Battering ram 8 0 0 0 0
Siege tower 9 0 0 0 0
Moat / ladder 10 0 0 0 0

Siege types use the projectile / siege path instead of this table.

Counter-attack damage (runtime, not table)#

Unit counter_atk_damage
Swordsman 300
Maceman 100
Knight 200
Others 0

Formation tier thresholds (0x004f4b28)#

Three uint32 per map-size row (12 bytes stride). Loaded into lotr2_combat_form_tier_thresh_* at battle init.

Map row Largest (tier 0) Tier 1 Tier 2 Smallest (tier 3)
0 ≥ 3 ≥ 2 ≥ 1 < 1
1 ≥ 6 ≥ 4 ≥ 2 < 2
2 ≥ 12 ≥ 8 ≥ 3 < 3
3 ≥ 24 ≥ 16 ≥ 6 < 6
4 ≥ 48 ≥ 32 ≥ 12 < 12

Target range (0x004f4be8)#

Per unit type, used for acquisition / line-of-fire.

ID Unit Range
0 Peasant 0
1 Archer 4
2 Swordsman 1
3 Maceman 2
4 Pikesman 5
5 Crossbowman 3
6 Knight 6
7 Catapult 10
8 Battering ram 8
9 Siege tower 9
10 Moat / ladder 7

Spawn templates (0x004f49f8, stride 0x14)#

ID Stack size Sub-template Walk steps / tile
0 Peasant 12 0 2
1 Archer 8 2 2
2 Swordsman 8 0 1
3 Maceman 8 0 3
4 Pikesman 10 0 4
5 Crossbowman 12 1 2
6 Knight 6 0 0
7 Catapult 2 3 5
8 Battering ram 2 0 5
9 Siege tower 2 0 5
10 Moat / ladder 1 0 5

Type 10 army count is multiplied by base squad size at battle spawn.


Siege sub-templates (0x004f4ad8, stride 0x14)#

Field at sub-template +0x0C → spawn projectile_damage on the figure.

Sub Param0 Param1 Param2 Projectile dmg Param4
0 0 0 0 0 0
1 120 50 4 50 0
2 64 100 4 200 8
3 160 100 4 200 16
4 3 2 1 6 4
5 2 12 8 3 24
6 16 6 48 32 12
7 96 64 24 192 128

Catapult (type 7) uses sub-template 3 → projectile damage 200 at spawn.


Infantry movement (animation step bases)#

From lotr2_combat_update_move_step // was thunk_FUN_00496fa3 @ 0x00496fa3 (types 0–6 only).

Unit Primary Secondary Strafe bonus
Peasant 10 9 6
Archer, Crossbowman 13 9 6
Swordsman, Maceman 12 11 6
Pikesman 8 7 6
Knight table @ 0x004f4f50

Walk counter must reach 0x11 (17) to complete a tile. MP speed adds +4 / +8 / +16 per sub-step vs +2 in SP.


Siege tick timing (per-type handlers)#

ID Wind-up (cb) Anim base (b2)
7 Catapult 20 45
8 Ram 15 40
9 Tower 30 60
10 Moat / ladder 8 50

Army strength multiplier (UI only)#

From head-count scoring loop; types 7–10 excluded.

Unit Multiplier
Peasant ×1
Archer, Pikesman, Crossbowman ×2
Swordsman, Maceman ×3
Knight ×4

Auto-calc strength multipliers#

Used by lotr2_game_army_calc_combat_strength for quick-resolve battles. Not the same table as the UI display multipliers above. Infantry types 0–6 only; siege types excluded.

Regenerate: python3 tools/ghidra/dump_combat_tables.py --all

Spec: ../spec/combat/auto-calculation.md

Retail (0x004f9f60)#

Unit ID Multiplier
Peasant 0 1
Archer 1 4
Swordsman 2 5
Maceman 3 5
Pikesman 4 3
Crossbowman 5 4
Knight 6 7

GoG (0x004d4b98)#

Unit ID Multiplier
Peasant 0 2
Archer 1 16
Swordsman 2 8
Maceman 3 13
Pikesman 4 9
Crossbowman 5 13
Knight 6 22

Auto-calc casualty thresholds#

Piecewise lookup for winner survivor % from strength ratio. See spec for full retail and GoG tables (0x004f9f10 / 0x004de710).


Catapult boulder damage (0x004f4c70)#

Indexed by projectile phase_timer >> 1. Values 19–24.

[ 0.. 7]: [24, 24, 24, 24, 24, 24, 24, 24]
[ 8..15]: [23, 23, 23, 23, 23, 23, 23, 23]
[16..23]: [22, 22, 22, 22, 22, 22, 22, 22]
[24..31]: [20, 20, 20, 20, 19, 19, 19, 19]

Boiling oil pour damage (0x004f4cc8)#

Indexed by projectile phase_timer >> 4. Values 25–32.

[25, 26, 32, 31, 30, 29, 28, 27, 26, 25, 32, 31, 30, 29, 28, 27]

Gate / wall thresholds#

Constant Value Meaning
lotr2_siege_gate_break_threshold 15 (0xf) Gate / manual hack breaks after this many hits
Wall breach > 15 on tile damage_counter Triggers breach tile type

Static table address map#

VA Contents
0x004f4c18 Melee attack damage (11×4 uint16)
0x004f4b28 Formation tier thresholds
0x004f4980 Base squad size by map row
0x004f4be8 Unit target range
0x004f49f8 Spawn templates
0x004f4ad8 Siege sub-templates
0x004f4c70 Catapult boulder damage
0x004f4cc8 Oil pour damage
0x004f4f50 Knight movement
0x004f4bc8 Battle setup unit order (8 slots)
PTR_LAB_004f46a0 Per-type tick handler table (11 entries)
0x004f9f60 Auto-calc strength multipliers (retail)
0x004f9f10 Auto-calc casualty thresholds (retail)
0x004d4b98 Auto-calc strength multipliers (GoG)
0x004de710 Auto-calc casualty thresholds (GoG)