DOTA2 的护甲,
到底递不递减?
玩 DOTA2 久了,总会撞见这场架。
递减派说:10 点护甲减伤 37.5%,20 点 54.5%,30 点 64.3%。同样加 10 点,涨幅一次比一次小,这还不叫递减?
线性派说:每 1 点护甲,都让你多扛相当于 6% 血量的物理伤害。第 1 点是这样,第 30 点也是这样,哪来的递减?
折中派出来打圆场:绝对收益线性,相对收益递减。
这几种说法,我在知乎、B 站和各种攻略里都见过很多回。几方的算术其实都对,吵不出结果,是因为大家在用不同的尺子量同一样东西。
先看公式
DOTA2 现在的护甲公式长这样:
这个公式比 DOTA2 还老。DotA 原本是《魔兽争霸 3》的一张自定义地图,护甲规则用的是魔兽 3 的,魔兽 3 的公式就是这个。DOTA2 中途改过两次,2020 年又改了回来,后面单独说。
把它画出来,就是递减派最爱的那条曲线:
曲线越来越平,这一点谁也不否认。要问的是:减伤百分比,是不是衡量“护甲有多大用”的那把尺子?
换一把尺子
护甲的用处,是让你多挨几下。所以更直接的问法是:有了这么多护甲,你一共能扛多少物理伤害?
减伤 37.5%,意思是每 100 点伤害你只吃 62.5 点。一个 2000 血的英雄,要挨满 3200 点物理伤害才会倒下。这个数叫有效血量。
下面用几个字母:H 是血量,A 是护甲,k = 0.06,E 是物理有效血量。第一条定理很简单,却是后面所有定理的地基。
对任意 A ≥ 0,
每 1 点护甲让有效血量增加 kH,与已有的护甲多少无关。
证明受到的伤害比例是 1 − R = 1/(1 + kA),所以 E = H/(1 − R) = H(1 + kA)。∎
这是一条直线,第 1 点护甲和第 50 点一样值钱。1/k 约等于 16.7,于是有两个好记的说法。第一,每攒够 16.7 点护甲,就相当于多了一条命。第二,有效血量和 H × (A + 16.7) 成正比,就好像每个英雄天生多带了 16.7 点看不见的护甲。这 16.7 点“隐藏护甲”后面还会出场。
把同一组护甲同时放到两把尺子上量,一把是弯的,一把是直的:
这两把尺子,魔兽 3 时代就有人弄混过。一个老牌的魔兽 3 入门教程里写着:20 点护甲大约相当于多了 55% 的血,100 血变成 155 血。按定理 1 应该是 220 血。减伤 55%,有效血量多的不是 55%,而是 120%。
油耗错觉
减伤百分比这把尺子,毛病出在哪?2008 年《科学》杂志上有篇论文,讲过一个一模一样的坑。
美国人用 MPG(每加仑油能跑几英里)标油耗。杜克大学的 Larrick 和 Soll 请人比较两种换车方案:开 1 万英里,从 18 MPG 换到 28 MPG,和从 34 MPG 换到 50 MPG,哪种省的油多?多数人选后一种。其实前一种省 198 加仑,后一种只省 94 加仑。
你真正在乎的“烧多少油”和 MPG 互为倒数。在倒数的尺子上,前面的一小步,抵得上后面的一大步。两位作者管这叫“MPG 错觉”。
护甲掉进的是同一个坑,方向反过来:E/H = 1/(1 − R)。减伤从 50% 涨到 60%,你能扛的从 2 管血变成 2.5 管;从 60% 涨到 70%,从 2.5 管变成 3.3 管。同样是 10 个百分点,越往后越值钱。当然,越往后涨 10 个百分点要的护甲也越多。两头一抵,摊到每点护甲上,还是 kH。
相对递减,谁不递减
那折中派的“绝对收益线性、相对收益递减”呢?这句话完全正确,只是它对什么都成立。
身上 0 点护甲时买一件锁子甲(+4 护甲),有效血量涨 24%;已经有 20 点时再买一件,只涨 10.9%。换成血量:1000 血时买一个活力之球(+250 血),涨 25%;到了 2250 血再买,只涨 11.1%。
可是很少有人说“血量收益递减”。任何往上加的东西,加在越大的底数上,占的比例就越小。月薪 3000 涨 1000 块,觉得涨了三成;月薪 3 万涨 1000 块,几乎没感觉。可这 1000 块能买的东西是一样多的。
所以,“相对递减”不是护甲的脾气,是加法的脾气。拿它回答不了“该不该买护甲”。
往七个方向推广
到这里,架其实已经吵完了。可数学好玩的部分在后头:一个结论成立以后,可以接着问,它在多大的范围里还成立。
波利亚在《怎样解题》里,把推广、特殊化和类比都当作解题的常规动作。推广的套路无非几种:把常数换成参数,把一个变量换成几个,把静止的换成随时间变的,把定义域往外延,把模型整个换掉。对护甲,我想到七个方向,每个方向一条定理:
下面一条一条来。每条先写结论,再给证明,证明都只有几行。不想看证明的,可以只看后面的“人话”。
刀刃定理
第一个方向:把公式里的常数换成参数。最自然的一族公式是 R = αA/(β + γA),现在 DOTA2 用的是 α = γ = 0.06、β = 1。护甲无穷大时,减伤趋向 α/γ,这是公式允许的最大减伤。
对减伤公式 R = αA/(β + γA)(α, β, γ > 0):
- ①最大减伤 α/γ < 100%:有效血量是凹的,护甲收益递减,有效血量有上限 γH/(γ − α)。
- ②α/γ = 100%:有效血量是直线。
- ③α/γ > 100%:有效血量是凸的,护甲收益递增;护甲到 β/(α − γ) 时,减伤达到 100%。
证明记 δ = α − γ,则
求两次导数,得 E″ = 2αβδH/(β − δA)3。在公式有效的范围里分母为正,所以 E″ 和 δ 同号。δ < 0 时令 A → ∞,即得上限。∎
人话公式允许的最大减伤,决定了曲线往哪边弯。100% 是一道刀刃,正好站在刀刃上,才是直线。
现在的公式,最大减伤 0.06/0.06 = 100%,正好站在刀刃上。7.20 版本的公式是 R = 0.052A/(0.9 + 0.048A),最大减伤 0.052/0.048 ≈ 108%,落到了凸的那一边。那一年半多里,护甲收益是递增的:0 甲时每点值 5.8% 血量,20 甲时 7.0%,40 甲时 8.5%。按定理 2,护甲到 0.9/0.004 = 225 点时减伤是 100%。当然,谁也堆不到。
所以,如果你在 2019 年说“护甲越堆越值”,你说得没错。递减派、线性派之外,其实还该有个递增派。
如果要求每一点护甲带来的有效血量都一样多,减伤公式只能是 R = kA/(1 + kA)。
证明每点一样多,就是 E/H = 1 + kA。由 E/H = 1/(1 − R) 反解出 R 即可。∎
斧王的账本
第二个方向:从一种属性变成两种。定理 1 说 E = kH(A + 1/k),血量和“护甲加 16.7”是乘在一起的。乘积有个老脾气:两个数的和固定时,两数相等,乘积最大。
设每点血要 cH 金,每点甲要 cA 金,价格固定,手里有一笔钱可以随意分。有效血量最大,当且仅当
也就是血的“身价”等于护甲(连同 16.7 点隐藏护甲)的“身价”。左边大,下一笔钱该买甲;右边大,该买血。
证明令 u = cH H,v = cA(A + 1/k)。由定理 1,E = k·uv/(cH cA)。不管钱怎么分,花掉 g 金,u + v 都正好增加 g,所以 u + v 是定值。由均值不等式 uv ≤ ((u + v)/2)2,等号当且仅当 u = v。∎
代入 7.41 的价格:活力之球 1000 金 250 血,cH = 4;锁子甲 500 金 4 甲,cA = 125。配平条件变成
这条线有两层意思。线的上方,同样的钱买锁子甲换来的有效血量更多;线的下方,买活力之球更多。它同时是最优路线:不管从哪出发,先补少的那一边,走到线上以后,沿着线一起涨。
人话血和甲要“等价”。不是点数相等,是按金币算相等。
这条线压得很低。20 点护甲的英雄,血量过了 1146,锁子甲就更划算。刚出门的英雄大约在线附近;之后升级加的血多、加的甲少,越往后越落在线的上方。递减派其实说中了一半:甲堆到很高以后,再买甲确实不如买血。原因却不是护甲递减,而是血相对少了。
这笔账只算了物理伤害。血还防魔法和纯粹伤害,护甲不管;实际的装备也很少只加一种属性。所以它指的是一个方向,不是出装公式。
尺子定理
第三个方向:换掉目标。前面一直在问“有效血量多了多少”,可你真正在乎的,也许是“活下来的概率”,也许是“能多撑几秒”。把你在乎的东西写成有效血量的函数 f(E),就有:
护甲的收益曲线 f(E(A)),和 f 本身弯向同一边:
f 凹,护甲收益递减;f 直,线性;f 凸,递增。
证明由定理 1,E 是 A 的一次函数,dE/dA = kH。用链式法则求两次导数即得。∎
人话护甲自己不弯,弯的是你拿来量它的尺子。
把开头的几派人放进这条定理,就是一张表:
| 你在乎的 f | f 的形状 | 护甲收益 | 谁 |
|---|---|---|---|
| 面板减伤 1 − H/E | 凹 | 递减 | 递减派 |
| 比上一件涨几成 ln E | 凹 | 递减 | 折中派 |
| 有效血量 E | 直 | 线性 | 线性派 |
| 有回血时能撑多久 | 凸 | 递增 | 递增派 |
| 扛过一波爆发的概率 | 先凸后凹 | 先增后减 | ? |
表里后两行更有意思,各自值一条推论。
对面每秒打你 d 点物理伤害,你每秒回 r 点血。你能撑的时间是
它是 E 的凸函数,所以护甲收益递增。当 A ≥ (d/r − 1)/k 时 T = ∞:回血比掉血快,打不死了。
证明每秒净掉血 d/(1 + kA) − r,用 H 除以它,化简即得 T。对 E 求两次导数,T″ = 2H2dr/(Hd − rE)3 > 0。∎
举个玩具例子:2000 血,被每秒 100 点伤害围着打,每秒回 20 点血。0 甲撑 25 秒,20 甲撑 79 秒,40 甲撑 213 秒;堆到 66.7 甲,就永远打不死了。不回血的话,同样的护甲只撑 20、44、68 秒。
“肉装配回血,越堆越肉”,背后就是这条推论。
对面一波爆发的伤害 D 不确定,设它服从均值 μ、标准差 σ 的正态分布。你扛过这一波的概率是
它在 E < μ 时是凸的,在 E > μ 时是凹的。护甲收益先递增、后递减,转折点在“有效血量刚好等于对面平均爆发”的地方。
证明Φ 是正态分布的累积分布函数,Φ″(x) = −xφ(x),其中 φ 是钟形的密度函数。它在 x < 0 时为正,x > 0 时为负。再用定理 4。∎
例子:2000 血,对面平均爆发 4000,标准差 600。10 甲时扛过的概率是 9%,16.7 甲时 50%,20 甲时 75%,30 甲时 99.6%。从 10 甲到 20 甲,概率涨了 66 个百分点;从 20 甲到 30 甲,只涨 25 个百分点。
所以“递增”和“递减”可以同时为真,就看你离生死线有多远。“看对面阵容出装”,大概就是这条推论的口语版。
时有时无的护甲
第四个方向:让护甲随时间变。很多护甲是临时的,技能开着时有,关了就没了。
护甲随时间变化,伤害均匀地打过来,和护甲的开关无关。那么平均受伤比例,总不小于“平均护甲”对应的受伤比例:
比如从 0 甲算起,开着的时间占 u,开着时多 a 点,它只相当于一直开着
点,比 ua 少。
证明受伤比例 m(A) = 1/(1 + kA) 是凸函数,由 Jensen 不等式即得第一式。第二式是解方程 1/(1 + kAeq) = u/(1 + ka) + (1 − u)。∎
人话一半时间 +20 甲,只相当于一直 +6.25 甲,不是 +10。
换成有效血量的说法:按时间平均时,有效血量取的是调和平均,而调和平均永远不大于算术平均。
这条定理有个前提:伤害和护甲的开关无关。如果护甲专挑挨打的时候开,比如团战前一秒开技能,这个亏就不吃了。“主动护甲要掐着点开”这句经验,数学给了它一个价钱:掐不准点,一半时间的 +20 甲只值 6.25 点。
负护甲:斯拉达定理
第五个方向:把定义域往外延,过零点。
护甲为负时,受伤比例是 m(A) = 2 − 1/(1 + k|A|)。于是:
- ①受伤比例的曲线关于点 (0, 1) 中心对称:m(A) + m(−A) = 2。+10 甲少受 37.5% 伤害,−10 甲就多受 37.5%。
- ②受到的伤害最多翻倍,有效血量永远大于 H/2。
- ③每多减 1 点甲,有效血量少 kH/(1 + 2k|A|)2,越减越少:这才是真正的收益递减。
证明①把两段公式相加。②|A| → ∞ 时 m → 2。③这时 E = H(1 + k|A|)/(1 + 2k|A|),对 |A| 求导即得。∎
人话减甲在对面护甲还是正数时,每点都满额;减到负数,开始打折。从 0 减到 −10,对面少扛相当于 27% 血量的伤害;再减 10 点,只少 8%;再减 10 点,只少 4%。
①里还藏着一个细节。中心对称保证了两段公式在零点处斜率相同,曲线光滑地接上;但有效血量的弯曲程度在零点跳了一下,一边是 0,一边是 4k2H。数学上说,它一阶光滑,二阶不光滑。玩家感觉不到这道缝。
护甲的家谱
第六个方向:换掉机制本身。游戏里的减伤不止护甲一种。把几种常见的机制都换算成有效血量,让它们从同一个起点、用同样的初速度出发:
DOTA2 的魔抗按乘法叠加。英雄基础魔抗一般是 25%,再叠 n 件、每件 r 的魔抗装备,受到的魔法伤害比例是 0.75(1 − r)n,所以魔法有效血量
随件数指数增长。绝对收益递增,相对收益不变,和护甲正好反过来。
证明每多一件,受伤比例乘以 1 − r,有效血量乘以 1/(1 − r) > 1,相邻两件带来的增量之比也是 1/(1 − r)。∎
人话按有效血量算,在 DOTA2 里越堆越值的不是护甲,是魔抗。
固定格挡(每次攻击减掉固定的伤害)也值得一提。对每一下 d 点的攻击,格挡 b 点的效果和“减伤 b/d”一样,属于加法叠加,到 b = d 时免疫。它的特点是看每一下有多疼:对小兵的小伤害几乎免疫,对一刀几百的大伤害几乎没用。用定理 4 的话说,这是把“伤害的大小”也变成了变量。
为什么设计者偏爱双曲型?我的猜测还是刀刃定理:它是唯一让每点护甲都一样值钱的公式,护甲永远不会废,也永远不会超模。乘法叠加和加法叠加都会让堆叠失控,前者慢慢失控,后者在 100% 处直接爆掉。DOTA2 的魔抗没出事,大概是因为能叠的魔抗装备本来就少。
隔壁英雄联盟
最后一个方向:换个游戏。英雄联盟的护甲公式是
也就是 k = 0.01:每点护甲让有效血量多 1%,DOTA2 是 6%。所以 1 点 DOTA2 护甲大约顶 6 点英雄联盟护甲,隐藏护甲也从 16.7 变成了 100。负护甲同样是 2 − 100/(100 − A),同样中心对称,同样最多翻倍。
前面的定理在英雄联盟里原样成立,只是常数不同。比如斧王定理:红水晶 400 金 150 血,布甲 300 金 15 甲,配平线是 H = 750 + 7.5A。顺手算一下隐藏护甲的身价:DOTA2 是 16.7 × 125 ≈ 2083 金,英雄联盟是 100 × 20 = 2000 金。两个游戏差不多,算个巧合。
不一样的地方有两处。一是英雄联盟的魔抗也用同一个双曲公式,不像 DOTA2 按乘法叠。二是英雄联盟有一整套穿甲和减甲:固定穿甲(穿透)、百分比穿甲,还有减甲。几样叠在一起时,顺序很要紧。
对护甲为 A > 0 的目标,设有固定穿甲 P、百分比穿甲 p。
- ①顺序不能交换:先打折再减,剩 (1 − p)A − P;先减再打折,剩 (1 − p)(A − P)。前者少 pP。英雄联盟规定先打折、再减,对攻击方更有利。
- ②只用一种时,固定穿甲比百分比穿甲更值,当且仅当 A < P/p。
证明①展开即得。②由定理 1(这里 k = 0.01),目标的有效血量减少 kH 乘以“被穿掉的护甲”。固定穿甲穿掉 P,百分比穿甲穿掉 pA,比大小即可。这里假设护甲没被穿到零以下,英雄联盟的穿甲本来也穿不到零以下。∎
人话固定穿甲打脆皮,百分比穿甲打坦克,分界线是 P/p。比如 18 点穿甲对 30% 穿甲,分界在 60 甲。
①有个更熟悉的版本:双十一。一张立减 50 元的券和一张八折券一起用在 300 元的东西上,先打折再减是 190 元,先减再打折是 200 元,差的 10 块正好是 50 × 20%。英雄联盟的减甲和穿甲,就是一叠不能随便换顺序的优惠券:减甲先减固定值再打折,穿甲先打折再减固定值。
我的看法
一、“递不递减”是尺子的性质,不是护甲的性质。
定理 4 说得很清楚:护甲本身是直的,弯的是你拿来量它的那个 f。几派人吵不出结果,是因为各自手里的 f 不一样,又都没说出来。
二、做决定,只看边际。
该不该买护甲,不看曲线弯不弯,看每块钱换来什么。斧王定理把这件事变成了一条直线:血多补甲,甲多补血,真正吃亏的是偏科。
三、好的公式站在刀刃上。
双曲公式是唯一让每点护甲都一样值钱的公式。我猜这就是它从魔兽 3 一路传到 DOTA2 和英雄联盟的原因:护甲永远不会废,也永远不会超模。7.20 往刀刃外迈了一步,一年半以后又退了回来。
之前数唐诗,我说数字会数、不会读。这一期是同一件事的另一面:同一组数字,换一把尺子读,“递减”就成了“线性”,甚至“递增”。
写在最后
下次再有人说护甲递减,不妨先问一句:你用的是哪把尺子?
“曲线弯不弯,
要看你拿的是哪把尺子。
你还为哪个游戏机制吵过架?留言区说说,说不定下次就写它。
- 版本:DOTA2 的护甲公式和物品价格按 7.41;英雄联盟的公式和物品价格按英雄联盟 Wiki 现行页面。
- 范围:只算物理伤害(第 11 节的魔抗除外)。闪避、格挡和各种减伤技能都不算。
- 有效血量:血量 ÷ 受到的伤害比例。护甲为正时,等于 H(1 + kA)。
- 配平线:每 1000 金,锁子甲带来 0.48H 的有效血量,活力之球带来 250(1 + kA),两者相等即得。
- 玩具模型:推论 4.1、4.2 里的伤害、回血和爆发都是为了演示虚构的数,不是实测。“凹”“凸”都指在公式有效的范围里。
- Liquipedia Dota 2 Wiki:Armor、Magic Resistance 词条(公式、叠加方式与历次改动)
- DOTA2 官方更新日志:7.07(2017-11-01)、7.20(2018-11-19)、7.27(2020-06-28)、7.41
- League of Legends Wiki:Armor、Armor penetration、Gold efficiency 词条
- Hive Workshop:Warcraft III Basics: Armor and Weapon Types
- R. P. Larrick & J. B. Soll, The MPG Illusion, Science 320: 1593–1594, 2008
- 波利亚《怎样解题》
- 知乎、B 站专栏和 17173 上关于护甲收益是否递减的讨论
Does Dota 2 Armor
Really Diminish?
Play Dota 2 long enough and you will run into this argument.
The diminishing camp says: 10 armor reduces damage by 37.5%, 20 armor by 54.5%, 30 armor by 64.3%. Each extra 10 points buys less than the last. If that isn't diminishing returns, what is?
The linear camp says: every point of armor lets you absorb extra physical damage equal to 6% of your HP. That holds for the 1st point and for the 30th. Where is the diminishing?
The compromise camp steps in to keep the peace: absolute returns are linear, relative returns diminish.
I have seen all of these claims many times, on Zhihu, on Bilibili and in all kinds of guides. Everyone's arithmetic is in fact correct. The argument goes nowhere because people are measuring the same thing with different rulers.
The formula first
Here is Dota 2's armor formula as it stands today:
This formula is older than Dota 2. DotA started out as a custom map for Warcraft III and borrowed its armor rules; this formula is Warcraft III's. Dota 2 changed it twice along the way and changed it back in 2020; more on that later.
Plot it and you get the diminishing camp's favorite curve:
Nobody disputes that the curve flattens. The question is: is the damage-reduction percentage the right ruler for measuring “how useful armor is”?
Change the ruler
Armor is there so you can take more hits. So the more direct question is: with this much armor, how much physical damage can you absorb in total?
A 37.5% damage reduction means that out of every 100 damage you take only 62.5. A hero with 2000 HP has to soak up a full 3200 physical damage before going down. This number is called effective HP.
A few letters from here on: H is HP, A is armor, k = 0.06, and E is physical effective HP. The first theorem is simple, but every theorem after it is built on it.
For every A ≥ 0,
Each point of armor adds kH to effective HP, however much armor you already have.
ProofThe fraction of damage you take is 1 − R = 1/(1 + kA), so E = H/(1 − R) = H(1 + kA).∎
This is a straight line: the 1st point of armor is worth exactly as much as the 50th. Since 1/k is about 16.7, there are two easy ways to remember it. First, every 16.7 armor you collect is worth one extra life. Second, effective HP is proportional to H × (A + 16.7), as if every hero were born with 16.7 points of invisible armor. These 16.7 points of “hidden armor” will come back later.
Put the same armor values on both rulers at once. One ruler is bent; the other is straight:
People were already mixing up these two rulers in the Warcraft III days. A long-standing Warcraft III beginner's guide says that 20 armor is roughly like having 55% more HP: 100 HP becomes 155. By Theorem 1 it should be 220. A 55% damage reduction does not give you 55% more effective HP but 120% more.
The MPG illusion
So what is wrong with the damage-reduction ruler? A 2008 paper in Science describes exactly the same trap.
Americans rate fuel economy in MPG (miles per gallon). Larrick and Soll of Duke University asked people to compare two car upgrades: over 10,000 miles, which saves more fuel, going from 18 MPG to 28 MPG, or from 34 MPG to 50 MPG? Most people picked the second. In fact the first saves 198 gallons and the second only 94.
What you actually care about, how much fuel you burn, is the reciprocal of MPG. On a reciprocal ruler, a small step at the low end is worth a big step at the high end. The two authors call this the “MPG illusion.”
Armor falls into the same trap, in the opposite direction: E/H = 1/(1 − R). When damage reduction goes from 50% to 60%, what you can absorb goes from 2 health bars to 2.5; from 60% to 70%, it goes from 2.5 bars to 3.3. The same 10 percentage points are worth more the further along you are. Of course, each further 10 percentage points also costs more armor. The two effects cancel out, and per point of armor the gain is still kH.
Relatively, everything diminishes
And the compromise camp's “absolute returns are linear, relative returns diminish”? It is perfectly true. It is just true of everything.
Buy a Chainmail (+4 armor) at 0 armor and your effective HP goes up 24%; buy another when you already have 20 armor and it goes up only 10.9%. Now do the same with HP: a Vitality Booster (+250 HP) bought at 1000 HP adds 25%; bought at 2250 HP, it adds only 11.1%.
Yet hardly anyone talks about “diminishing returns on HP.” Anything you add makes up a smaller share of a bigger base. On a salary of 3,000 yuan a month, a 1,000-yuan raise feels like a third more; on 30,000 a month, you barely notice it. But those 1,000 yuan buy exactly as much either way.
So “relatively diminishing” is not a quirk of armor; it is a quirk of addition. It cannot tell you whether to buy armor.
Generalizing in seven directions
At this point the argument is really over. But the fun part of mathematics comes afterwards: once a result holds, you can go on to ask how far it reaches.
In “How to Solve It,” Pólya treats generalization, specialization and analogy as routine moves in problem solving. There are only a handful of ways to generalize: turn a constant into a parameter, one variable into several, something static into something that changes over time, extend the domain, or replace the model altogether. For armor I came up with seven directions, one theorem each:
Let's take them one at a time. For each, I state the result first and then give the proof, which never runs more than a few lines. If you'd rather skip the proofs, just read the “In plain English” note after each one.
The Knife-Edge Theorem
The first direction: turn the constants in the formula into parameters. The most natural family of formulas is R = αA/(β + γA); Dota 2 currently uses α = γ = 0.06 and β = 1. As armor goes to infinity, the reduction approaches α/γ, the largest reduction the formula allows.
For the damage-reduction formula R = αA/(β + γA) (α, β, γ > 0):
- ① If the maximum reduction α/γ < 100%, effective HP is concave: armor has diminishing returns, and effective HP is capped at γH/(γ − α).
- ② If α/γ = 100%, effective HP is a straight line.
- ③ If α/γ > 100%, effective HP is convex: armor has increasing returns, and the reduction reaches 100% at β/(α − γ) armor.
ProofLet δ = α − γ. Then
Differentiating twice gives E″ = 2αβδH/(β − δA)3. Wherever the formula is valid the denominator is positive, so E″ has the same sign as δ. When δ < 0, letting A → ∞ gives the cap.∎
In plain EnglishThe largest reduction the formula allows decides which way the curve bends. 100% is a knife edge: only a formula balanced exactly on the edge gives a straight line.
Today's formula has a maximum reduction of 0.06/0.06 = 100%, right on the knife edge. The 7.20 formula was R = 0.052A/(0.9 + 0.048A), with a maximum reduction of 0.052/0.048 ≈ 108%, which puts it on the convex side. For more than a year and a half, armor had increasing returns: at 0 armor each point was worth 5.8% of your HP, at 20 armor 7.0%, at 40 armor 8.5%. By Theorem 2, the reduction would hit 100% at 0.9/0.004 = 225 armor. Of course, nobody could ever stack that much.
So if you said in 2019 that “armor gets better the more you stack,” you were right. Besides the diminishing camp and the linear camp, there really should have been an increasing camp.
If every point of armor is to add the same amount of effective HP, the damage-reduction formula has to be R = kA/(1 + kA).
ProofThe same amount for every point means E/H = 1 + kA. Solve E/H = 1/(1 − R) for R.∎
Axe's ledger
The second direction: go from one stat to two. Theorem 1 says E = kH(A + 1/k), so HP and “armor plus 16.7” are multiplied together. Products have an old habit: when two numbers have a fixed sum, their product is largest when they are equal.
Suppose HP costs cH gold per point and armor costs cA gold per point, prices are fixed, and you have a sum of gold to split however you like. Effective HP is largest if and only if
that is, when your HP is “worth” as much as your armor (counting the 16.7 points of hidden armor). If the left side is bigger, your next gold should go into armor; if the right side is bigger, into HP.
ProofLet u = cH H and v = cA(A + 1/k). By Theorem 1, E = k·uv/(cH cA). However the gold is split, spending g gold raises u + v by exactly g, so u + v is fixed. By the AM–GM inequality, uv ≤ ((u + v)/2)2, with equality if and only if u = v.∎
Plug in the 7.41 prices: a Vitality Booster is 1000 gold for 250 HP, so cH = 4; a Chainmail is 500 gold for 4 armor, so cA = 125. The balance condition becomes
This line means two things. Above it, the same gold buys more effective HP as Chainmail; below it, as Vitality Booster. It is also the optimal path: wherever you start, first top up whichever side is short, and once you reach the line, grow both together along it.
In plain EnglishHP and armor should be “equal,” not in points but in gold.
This line sits very low. For a hero with 20 armor, once HP passes 1146, Chainmail is the better buy. A hero leaving base at the start of the game sits roughly on the line; after that, levels add lots of HP and little armor, so as the game goes on you drift further above it. The diminishing camp was actually half right: once your armor is very high, more armor really is worse than more HP. But the reason is not that armor diminishes; it is that your HP has fallen behind.
This calculation counts only physical damage. HP also protects against magical and pure damage, which armor does nothing about, and real items rarely add just one stat. So it points in a direction; it is not a build formula.
The Ruler Theorem
The third direction: change the goal. So far we have been asking “how much did effective HP go up,” but what you really care about may be your chance of surviving, or how many more seconds you can last. Write what you care about as a function of effective HP, f(E), and you get:
The return curve of armor, f(E(A)), bends the same way as f itself:
If f is concave, armor has diminishing returns; if f is straight, linear returns; if f is convex, increasing returns.
ProofBy Theorem 1, E is a linear function of A with dE/dA = kH. Differentiate twice using the chain rule.∎
In plain EnglishArmor itself doesn't bend. What bends is the ruler you measure it with.
Put the camps from the beginning into this theorem and you get a table:
| Your goal f | Shape of f | Armor returns | Who |
|---|---|---|---|
| Displayed reduction 1 − H/E | Concave | Diminishing | Diminishing camp |
| Relative gain per item ln E | Concave | Diminishing | Compromise camp |
| Effective HP E | Straight | Linear | Linear camp |
| Survival time with regen | Convex | Increasing | Increasing camp |
| Chance of surviving a burst | S-shaped | Up, then down | ? |
The last two rows of the table are the more interesting ones, and each earns a corollary of its own.
The enemy deals you d physical damage per second, and you regenerate r HP per second. The time you can survive is
This is a convex function of E, so armor has increasing returns. When A ≥ (d/r − 1)/k, T = ∞: you regenerate faster than you lose HP, and you can no longer be killed.
ProofYou lose a net d/(1 + kA) − r HP per second; divide H by this and simplify to get T. Differentiating twice with respect to E gives T″ = 2H2dr/(Hd − rE)3 > 0.∎
A toy example: 2000 HP, surrounded and taking 100 damage per second, regenerating 20 HP per second. At 0 armor you last 25 seconds, at 20 armor 79 seconds, at 40 armor 213 seconds; stack 66.7 armor and you can never be killed. Without regen, the same armor keeps you alive for only 20, 44 and 68 seconds.
The folk wisdom “tank items plus regen get tankier the more you stack” rests on exactly this corollary.
The damage D of the enemy's burst is uncertain; suppose it is normally distributed with mean μ and standard deviation σ. Your chance of surviving the burst is
This is convex for E < μ and concave for E > μ. Armor's returns first increase, then diminish, and the turning point is where effective HP exactly equals the enemy's average burst.
ProofΦ is the cumulative distribution function of the normal distribution, and Φ″(x) = −xφ(x), where φ is the bell-shaped density. This is positive for x < 0 and negative for x > 0. Now apply Theorem 4.∎
An example: 2000 HP, and an enemy burst averaging 4000 with a standard deviation of 600. Your chance of surviving is 9% at 10 armor, 50% at 16.7, 75% at 20 and 99.6% at 30. From 10 to 20 armor the chance rises by 66 percentage points; from 20 to 30, by only 25.
So “increasing” and “diminishing” can both be true; it depends on how far you are from the life-or-death line. “Itemize against the enemy lineup” is more or less this corollary in everyday words.
Armor that comes and goes
The fourth direction: let armor change over time. A lot of armor is temporary: you have it while an ability is active and lose it when the ability ends.
Suppose armor varies over time, and damage arrives evenly, independent of when the armor is on or off. Then the average fraction of damage you take is never less than the fraction you would take at your “average armor”:
For example, starting from 0 armor, a bonus that is on a fraction u of the time and gives a armor while on is worth only as much as permanently having
points of armor, which is less than ua.
ProofThe fraction of damage taken, m(A) = 1/(1 + kA), is convex, so the first formula follows from Jensen's inequality. The second comes from solving 1/(1 + kAeq) = u/(1 + ka) + (1 − u).∎
In plain English+20 armor half the time is worth only +6.25 armor all the time, not +10.
In terms of effective HP: averaging over time gives you the harmonic mean of effective HP, and the harmonic mean is never larger than the arithmetic mean.
The theorem has one assumption: damage is independent of when the armor is on. If the armor switches on exactly when you are being hit, say you pop the ability a second before a team fight, you don't take this loss. The rule of thumb “time your active armor” now has a price tag: time it badly, and +20 armor half the time is worth just 6.25.
Negative armor: the Slardar Theorem
The fifth direction: extend the domain past zero.
When armor is negative, the fraction of damage taken is m(A) = 2 − 1/(1 + k|A|). Hence:
- ① The damage-taken curve is symmetric about the point (0, 1): m(A) + m(−A) = 2. If +10 armor means 37.5% less damage taken, −10 armor means 37.5% more.
- ② Damage taken at most doubles, and effective HP always stays above H/2.
- ③ Each further point of armor reduction lowers effective HP by kH/(1 + 2k|A|)2, less and less each time: this is diminishing returns for real.
Proof① Add the two formulas. ② As |A| → ∞, m → 2. ③ Here E = H(1 + k|A|)/(1 + 2k|A|); differentiate with respect to |A|.∎
In plain EnglishWhile the enemy's armor is still positive, every point of armor reduction counts in full; once it goes negative, it starts to be discounted. Taking armor from 0 to −10 cuts the damage the enemy can absorb by 27% of their HP; the next 10 points cut only 8%, and the 10 after that only 4%.
Point ① hides one more detail. The central symmetry makes the two pieces of the formula meet at zero with the same slope, so the curve joins smoothly. But the curvature of effective HP jumps at zero: it is 0 on one side and 4k2H on the other. In mathematical terms, it is smooth to first order but not to second order. Players can't feel this seam.
Armor's family tree
The sixth direction: change the mechanism itself. Armor is not the only way games reduce damage. Convert a few common mechanisms into effective HP and start them all from the same point with the same initial slope:
Magic resistance in Dota 2 stacks multiplicatively. A hero's base magic resistance is usually 25%; stack n magic-resistance items of r each on top of it, and the fraction of magic damage you take is 0.75(1 − r)n, so your magical effective HP is
which grows exponentially with the number of items. Absolute returns increase and relative returns stay constant, exactly the reverse of armor.
ProofEach extra item multiplies the fraction of damage taken by 1 − r and effective HP by 1/(1 − r) > 1; the ratio between the gains from two consecutive items is also 1/(1 − r).∎
In plain EnglishMeasured in effective HP, what gets better the more you stack in Dota 2 is not armor but magic resistance.
Flat damage block (subtracting a fixed amount from every attack) deserves a mention too. Against an attack of d damage, blocking b has the same effect as a reduction of b/d. It stacks additively and makes you immune once b = d. What sets it apart is that it depends on how hard each hit is: you are almost immune to the small hits of creeps, and it does almost nothing against big hits of several hundred. In the language of Theorem 4, it turns “the size of the damage” into a variable as well.
Why do designers favor the hyperbolic type? My guess, once again, is the knife-edge theorem: it is the only formula under which every point of armor is worth the same, so armor never becomes useless and never becomes overpowered. Multiplicative and additive mechanisms both let stacking get out of hand, the first slowly, the second blowing up outright at 100%. Dota 2's magic resistance has stayed under control, probably because there were never many stackable magic-resistance items to begin with.
Next door: League of Legends
The last direction: switch games. The armor formula in League of Legends is
that is, k = 0.01: each point of armor adds 1% to effective HP, against 6% in Dota 2. So 1 point of Dota 2 armor is worth about 6 points of League armor, and hidden armor goes from 16.7 to 100. For negative armor, the fraction of damage taken is likewise 2 − 100/(100 − A), likewise symmetric about the center, and likewise never more than double.
The earlier theorems hold unchanged in League of Legends; only the constants differ. Take the Axe Theorem: a Ruby Crystal is 400 gold for 150 HP, a Cloth Armor is 300 gold for 15 armor, and the balance line is H = 750 + 7.5A. While we're at it, here is what hidden armor is worth: 16.7 × 125 ≈ 2083 gold in Dota 2, 100 × 20 = 2000 gold in League. The two games come out about the same; call it a coincidence.
There are two differences. First, League of Legends uses the same hyperbolic formula for magic resist as well, rather than stacking it multiplicatively as Dota 2 does. Second, League has a whole system of armor penetration and armor reduction: flat penetration (lethality), percentage penetration, and armor reduction. When several of them apply together, the order matters a great deal.
Against a target with armor A > 0, suppose you have flat penetration P and percentage penetration p.
- ① The order cannot be swapped. Apply the percentage first and then subtract, and (1 − p)A − P is left; subtract first and then apply the percentage, and (1 − p)(A − P) is left. The first is smaller by pP. League of Legends applies the percentage first and the flat amount second, which favors the attacker.
- ② Using only one kind, flat penetration is worth more than percentage penetration if and only if A < P/p.
Proof① Expand. ② By Theorem 1 (here with k = 0.01), the target's effective HP drops by kH times “the armor penetrated.” Flat penetration removes P and percentage penetration removes pA; compare the two. This assumes armor is not penetrated below zero, which in League it cannot be anyway.∎
In plain EnglishFlat penetration for squishies, percentage penetration for tanks, with the break-even point at P/p. For example, 18 flat penetration against 30% penetration breaks even at 60 armor.
Point ① has a more familiar version: Singles' Day shopping. Use a ¥50-off coupon and a 20%-off coupon together on a ¥300 item. Take the 20% off first and then the ¥50, and you pay ¥190; take the ¥50 off first and then the 20%, and you pay ¥200. The ¥10 difference is exactly 50 × 20%. Armor reduction and penetration in League of Legends are a stack of coupons whose order you can't freely swap: armor reduction subtracts the flat amount first and then applies the percentage, while penetration applies the percentage first and then subtracts the flat amount.
My take
1. “Diminishing or not” is a property of the ruler, not of armor.
Theorem 4 makes it plain: armor itself is straight, and what bends is the f you measure it with. The camps can never settle the argument because each holds a different f, and none of them spells it out.
2. For decisions, look only at the margin.
Whether to buy armor depends not on whether the curve bends but on what each gold you spend gets you. The Axe Theorem turns this into a straight line: lots of HP, add armor; lots of armor, add HP. What really costs you is a lopsided build.
3. A good formula stands on the knife edge.
The hyperbolic formula is the only one under which every point of armor is worth the same. I suspect that is why it was handed down from Warcraft III to Dota 2 and League of Legends: armor never becomes useless and never becomes overpowered. Patch 7.20 took a step off the knife edge, and a year and a half later it stepped back.
When I counted Tang poems, I said that numbers can count but cannot read. This issue is the other side of the same coin: read the same numbers with a different ruler, and “diminishing” turns into “linear,” or even “increasing.”
In closing
Next time someone tells you armor has diminishing returns, try asking first: which ruler are you using?
“Whether a curve bends
depends on which ruler you hold.
What other game mechanic have you argued about? Tell me in the comments; maybe I'll write about it next time.
- Versions: the Dota 2 armor formula and item prices are from 7.41; the League of Legends formulas and item prices are from the current League of Legends Wiki pages.
- Scope: physical damage only (except for magic resistance in Section 11). Evasion, damage block and damage-reduction abilities are all left out.
- Effective HP: HP ÷ fraction of damage taken. With positive armor this equals H(1 + kA).
- Balance line: per 1000 gold, Chainmail adds 0.48H of effective HP and Vitality Booster adds 250(1 + kA); set the two equal.
- Toy models: the damage, regen and burst numbers in Corollaries 4.1 and 4.2 are made up for illustration, not measured. “Concave” and “convex” always refer to the range where the formula is valid.
- Liquipedia Dota 2 Wiki: the Armor and Magic Resistance pages (formulas, stacking and the history of changes)
- Official Dota 2 patch notes: 7.07 (2017-11-01), 7.20 (2018-11-19), 7.27 (2020-06-28), 7.41
- League of Legends Wiki: the Armor, Armor penetration and Gold efficiency pages
- Hive Workshop: Warcraft III Basics: Armor and Weapon Types
- R. P. Larrick & J. B. Soll, The MPG Illusion, Science 320: 1593–1594, 2008
- George Pólya, “How to Solve It”
- Discussions on Zhihu, Bilibili columns and 17173 about whether armor has diminishing returns