This patch changes the damage resistance (formerly armour) data type from a nonNegativeDecimal to an integer. The armour values are levels, not amounts; all armour values in 0 A.D. and in all mods I'm aware of are already integers in practice; I'm not sure either how to visualize a decimal level, e.g. 3.14; allowing something that's unlikely to happen seems a bit unnecessary, hence the change from decimal to integer.

As for dropping the nonNegative, this would make it easier for mods to implement a counter system via armour levels; e.g. instead of hard-coding a 1.5× bonus attack vs a specific unit type, one could simply give the target −4 armour of the relevant damage type to achieve the same effect.

See also D2247.

# Details

- Reviewers
Freagarach - Group Reviewers
Restricted Owners Package (Owns No Changed Paths)

Verify everything still works as before.

# Diff Detail

- Repository
- rP 0 A.D. Public Repository
- Branch
- /ps/trunk
- Lint
Lint OK - Unit
No Unit Test Coverage - Build Status
**Buildable 13002**Build 25641: Vulcan Build Jenkins Build 25640: Vulcan Build (macOS) Jenkins Build 25639: Vulcan Build (Windows) Jenkins Build 25638: arc lint + arc unit

### Event Timeline

Don't understand the change from decimals to integers, sounds like a regression to me. If all known mods use integers fine, but why disable any future mod wanting decimals? Also what about techs/auras wanting a +x% on armour?

Allowing negative values, might be worth considering, but needs some good look at the code to find potential loopholes.

Also what about techs/auras wanting a +x% on armour?

There are none. Unlike attack damage, health, resource costs, etc., resistance is exponential: +x means damage taken is multiplied by 0.9^x. The question is whether decimal levels really make sense.

Currently yes, but why disallow it for any future mod?

The question is whether decimal levels really make sense.

Again if a mod (let be the vanilla mod) wants integers, let it have it in the templates. While I see a benefit in keeping the more general decimal (namely more general modding support), I haven't found a benefit in restricting to integers. The handling code already is general enough. So what problem is solved with this patch?

Whether a parameter is a decimal or an integer appears to be a bit arbitrary in 0 A.D.; e.g. attack and heal ranges are decimals, whereas alert and vision ranges are integers.

For this patch it's very important to understand how armour/resistance works in 0 A.D.

- In
*Age of Empires*, armour is a flat value: if an enemy inflicts X damage on an entity with armour Y, then the target loses X - Y health. - In
*Age of Mythology*, armour is a fraction: if an enemy inflicts X damage on an entity with armour Y, then the target loses X × (1 - Y) health. - In
*0 A.D.*, armour is exponential: if an enemy inflicts X damage on an entity with armour Y, then the target loses X × 0.9^Y health.

Many (decimal) parameters in 0 A.D. allow both "add" and "multiply" operations; I'm not arguing that should be restricted. However, for armour those have different meanings: adding to an exponent is effectively a multiplication, whereas multiplying an exponent is effectively a power, an operation not allowed for other parameters.

The other usage of exponentials I know of in 0 A.D. is <ResourceSupply/DiminishingReturns> (in fields). However, here the (decimal) value is the base, whereas the exponent is the number of workers, which is an integer; e.g. 0.2 workers is not allowed either.

Realistically the only situation in which a mod would want to multiply or use decimal armour, is when armour works differently; but that requires that mod to alter code (at least `simulation/helpers/Attacking.js`) and while that is certainly not forbidden, it is not something the public mod should account for.

That the armour is the exponential is also the reason why – unlike for other parameters – negative armour values should be allowed: 0.9^-X = 1 / 0.9^X. Division by zero is impossible (0.9^0 = 1).