Why Does My Combat Power Calculation Differ from the Game?

Politics, religion, war. They are nothing without a legacy that can stand the test of time. Lead any nation, and turn it into a mighty kingdom in one of the most compelling grand strategy games ever created.

Moderator: FOGK Moderators

Post Reply
duirixuanyan
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 59
Joined: Mon Aug 05, 2019 3:11 pm

Why Does My Combat Power Calculation Differ from the Game?

Post by duirixuanyan »

Help me understand Combat Power calculation — my formula doesn't match the game

---

**TL;DR:** I tried to reverse-engineer `Unit_CombatPower` for Byzantine Light Archers (got ~9) and Skoutatoi (got ~32). But the game shows different numbers. Can anyone point out my mistakes or give me the actual in-game values so I can work backwards?

---

---

Hi everyone,

I've been trying to reverse-engineer the `Unit_CombatPower` function from `Unit.BSF` to understand how Combat Power is calculated. But my results don't match what the game shows. Can anyone help me figure out what I'm missing?

## The Formula (as I understand it)

From `Unit.BSF`:

```c
FUNCTION Unit_CombatPower(unitID)
{
attack = Unit_Attack(unitID) + (Unit_FlankingMod(unitID) / 2) + (Unit_AttackAssaultChange(unitID) / 2);
defense = Unit_Defense(unitID) + (Unit_DefenseAssaultChange(unitID) / 2);
range = Unit_RangedAttackValue(unitID) + Unit_RangedMaxEffecDamages(unitID);
xp = Unit_GetXPLevel(unitID);

base = (Unit_GetHits(unitID) * UNIT_CP_HIT_INCh) + (Unit_GetEffec(unitID) * UNIT_CP_EFF_INCh);
base += (attack * UNIT_CP_ATK_INCh) + (defense * UNIT_CP_DEF_INCh);
base += (range * UNIT_CP_RNG_INCh) + (xp * UNIT_CP_EXP_INCh);

mult = (Unit_GetHits(unitID) * UNIT_CP_HIT_PERC) + (Unit_GetEffec(unitID) * UNIT_CP_EFF_PERC);
mult += (attack * UNIT_CP_ATK_PERC) + (defense * UNIT_CP_DEF_PERC);
mult += (range * UNIT_CP_RNG_PERC) + (xp * UNIT_CP_EXP_PERC);

result = base * (100 + mult);
result = DivideAndRound(result, 10000);

result = Pow(result, UNIT_CP_NUMERATORh, UNIT_CP_DENOMINATORh) / 10; // ^1.66
result = Max(1, result);

if (Unit_TemplateKind(unitID) == KIND_NAV)
result /= 2;

return result;
}
```

With the constants (from the comments):

```
UNIT_CP_HIT_INCh = 100
UNIT_CP_EFF_INCh = 50
UNIT_CP_EXP_INCh = 35
UNIT_CP_ATK_INCh = 25
UNIT_CP_DEF_INCh = 25
UNIT_CP_RNG_INCh = 10

UNIT_CP_HIT_PERC = 8
UNIT_CP_EFF_PERC = 22
UNIT_CP_EXP_PERC = 18
UNIT_CP_ATK_PERC = 15
UNIT_CP_DEF_PERC = 15
UNIT_CP_RNG_PERC = 6
```

## Example 1: Byzantine Light Archers

| Stat | Value |
|---|---|
| Hits | 1 |
| Effectiveness | 3 |
| Attack | 3 |
| Defense | 3 |
| RangedAttack | 7 |
| RangedMaxDamages | 1 |
| FlankingModifier | 1 |
| AtkAssaultChg | 0 |
| DefAssaultChg | 1 |
| XP Level | 0 |

### My calculation

**Step 1 — Compute derived stats:**

```
attack = 3 + (1 / 2) + (0 / 2) = 3 + 0 + 0 = 3
defense = 3 + (1 / 2) = 3 + 0 = 3
range = 7 + 1 = 8
xp = 0
```

> Note: integer division, `1/2 = 0`.

**Step 2 — Base value:**

```
base = (1 × 100) + (3 × 50) = 100 + 150 = 250
base += (3 × 25) + (3 × 25) = 75 + 75 = 150
base += (8 × 10) + (0 × 35) = 80 + 0 = 80
base = 250 + 150 + 80 = 480
```

**Step 3 — Multiplier:**

```
mult = (1 × 8 ) + (3 × 22) = 8 + 66 = 74
mult += (3 × 15) + (3 × 15) = 45 + 45 = 90
mult += (8 × 6) + (0 × 18) = 48 + 0 = 48
mult = 74 + 90 + 48 = 212
```

**Step 4 — Combine:**

```
result = 480 × (100 + 212) = 480 × 312 = 149,760
result = 149,760 / 10,000 = 14.976
```

**Step 5 — Pow(1.66):**

```
14.976 ^ 1.66 ≈ ?
ln(14.976) ≈ 2.7063
1.66 × 2.7063 ≈ 4.4925
e^4.4925 ≈ 89.4
result = 89.4 / 10 = 8.94
```

**Step 6 — Final:**

```
result = max(1, 8.94) = 8.94 ≈ 9
```

**My result: ~9**

But the game shows 5. Can anyone tell me where the discrepancy comes from?

## Example 2: Skoutatoi

| Stat | Value |
|---|---|
| Hits | 3 |
| Effectiveness | 3 |
| Attack | 6 |
| Defense | 8 |
| RangedAttack | 0 |
| RangedMaxDamages | 0 |
| FlankingModifier | 1 |
| AtkAssaultChg | 1 |
| DefAssaultChg | 0 |
| XP Level | 0|

### My calculation

**Step 1 — Derived stats:**

```
attack = 6 + (1 / 2) + (1 / 2) = 6 + 0 + 0 = 6
defense = 8 + (0 / 2) = 8 + 0 = 8
range = 0 + 0 = 0
xp = 0
```

**Step 2 — Base value:**

```
base = (3 × 100) + (3 × 50) = 300 + 150 = 450
base += (6 × 25) + (8 × 25) = 150 + 200 = 350
base += (0 × 10) + (0 × 35) = 0 + 0 = 0
base = 450 + 350 + 0 = 800
```

**Step 3 — Multiplier:**

```
mult = (3 × 8 ) + (3 × 22) = 24 + 66 = 90
mult += (6 × 15) + (8 × 15) = 90 + 120 = 210
mult += (0 × 6) + (0 × 18) = 0 + 0 = 0
mult = 90 + 210 + 0 = 300
```

**Step 4 — Combine:**

```
result = 800 × (100 + 300) = 800 × 400 = 320,000
result = 320,000 / 10,000 = 32.0
```

**Step 5 — Pow(1.66):**

```
32 ^ 1.66 ≈ ?
ln(32) ≈ 3.4657
1.66 × 3.4657 ≈ 5.7531
e^5.7531 ≈ 315.4
result = 315.4 / 10 = 31.54
```

**Step 6 — Final:**

```
result = max(1, 31.54) = 31.54 ≈ 32
```

**My result: ~32**

But the game shows 12.

## My Questions

1. **Are my constants correct?** I got them from comments in `Unit.BSF`.

2. **Integer division truncation:** In `attack = Unit_Attack + (Flanking / 2) + (AtkAssaultChg / 2)`, does `1 / 2` become 0 (integer) or 0.5 (float)?

Thanks for any help!
Surt
Field Marshal - Me 410A
Field Marshal - Me 410A
Posts: 5148
Joined: Thu May 21, 2020 9:50 pm

Re: Why Does My Combat Power Calculation Differ from the Game?

Post by Surt »

Won't the result of step 4 be 15 as its divide and round?
There should be a file where the real numbers are.
There are 10 kind of hard problems in computer science, naming, cache invalidations and off-by-one errors.
There are also 10 kinds of people, those who understand binary and those who do not.
duirixuanyan
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 59
Joined: Mon Aug 05, 2019 3:11 pm

Re: Why Does My Combat Power Calculation Differ from the Game?

Post by duirixuanyan »

Thanks for replying.

Yes, the result of step 4 should be 15. However, the number still doesn't match which is confusing.
Surt
Field Marshal - Me 410A
Field Marshal - Me 410A
Posts: 5148
Joined: Thu May 21, 2020 9:50 pm

Re: Why Does My Combat Power Calculation Differ from the Game?

Post by Surt »

duirixuanyan wrote: Mon Oct 12, 2026 7:25 am Thanks for replying.

Yes, the result of step 4 should be 15. However, the number still doesn't match which is confusing.
Comments gets outdated so you need to find the file where the values are actually set.
There are 10 kind of hard problems in computer science, naming, cache invalidations and off-by-one errors.
There are also 10 kinds of people, those who understand binary and those who do not.
Post Reply

Return to “Field of Glory: Kingdoms”