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) |