游戏战斗力数值研究(一)

作者:老咸鱼 2020-02-28


昨天躺床上睡不着的时候想到了一个问题,很多游戏都有战斗力系统,通过一些角色属性计算出一个战斗力用来比较玩家之间的强弱等。这是一个非常经典常见的设计。

不过似乎是我脸比较黑,打一些游戏的竞技场之类的东西时,经常会出现“明明对方战力比我差一截,但我就是打不过去”这种匪夷所思的情况,而且这种情况还不在少数,难免倒人胃口。毕竟,战斗力这个数值设计就是用来衡量玩家的强弱的,但我既然更强却打不过弱的,怎么也说不过去。

所以我打算自己分析一下,从最简单的模型开始一点点增加变量,看看到底应该用怎么样的办法能更准确地计算战斗力的数值,并且尝试对其中部分做简单的证明来保证其科学性。

因为是边推导边发,一不小心咕了不说,可能有些地方会有疏漏和错误,望大家不吝赐教,提前谢过。

HA体系

先来看最简单的“生命-攻击”(HA)体系。

顾名思义,角色的属性只有两种,攻击力和生命值。在这一体系下,游戏的规则为:

1, 生命值小于等于0,角色死亡
2, A对B攻击,对B造成相当于A攻击力大小的伤害

这个体系和其下的规则相当简单,可以说是RPG类游戏的基础。引入其他诸如防御力,暴击,属性克制等内容对伤害公式进行修正和改进,就得到了市面上各种各样的RPG游戏。

我们首先假设两个角色A(Attack= ,Health= )和B(Attack= ,Health= ),并假定A强于B,在这一规则下,伤害公式应为



似乎有点过于简单以至于没有写的必要。不过,伤害公式是进行战斗力计算的关键,对于每一个体系列出伤害公式,才能有助于我们更好地判断战斗力的大小。所以虽然这个公式看起来很水,还是要列一下。

假定A先手,如果A不死亡,且A在自己的 回合后胜利,则对B累计造成的伤害为 ,自己受到B造成的 点伤害。而A胜利的唯一条件为击杀B,因此,应有如下两个不等式:


应该注意的是,由于先手优势,A能够比B多打出一轮伤害。而如果如之前假定A强于B,则A在后手时也应获胜。因而,类似的,有:


由于在后手情况下,A同样需要N回合击杀B,故不难证明:


将上式带入A后手情况得出的两个不等式,应有:


联立【1】【2】【3】三个不等式,【1】+【3】所得结果约去2,得:


由于 均为正值,移项并联立两式,有:


由于生命值与攻击力为定值,因此两者的乘积也必然为一常量。注意到我们在这个过程中并没有对 做出限定,因此,这一数值适用于HA体系下任意情况,并且可以准确衡量角色的真实强度。

定义


由这个公式可以得到一个有意思的结论:当可以在生命值和攻击力中二选一进行提升的时候,选择数值更低的进行提升收益更大。因而,这一体系下无脑堆血与玻璃大炮在单人游玩的情况下并不会产生很好的效果。如何证明自然也很简单,这里不再赘述。

另外,一些游戏为了保证每次攻击产生的数值均不同,引入了乱数补正的手段。一般来讲,乱数补正产生一个对称的区间,每次造成的伤害在其中随机取值,而整体期望仍为无补正时的数值大小,故对战斗力不产生影响。若区间不对称,则伤害值应修改为实际期望,战斗力公式也要相应修改。

例如,若引入乱数补正系数 ,上公式应修改为:


在以后的内容中,除非特殊说明,默认不讨论乱数补正的情况。

HADa体系

如果引入一点更复杂的变量呢?

我们试着引入一个防御看一看。

不同游戏对于防御的设定也不同。有些游戏采用防御抵消等值攻击的做法,例如,如果一个原本为10点伤害的攻击打到一个防御为5点的角色上,则这个角色应受到5点伤害,而如果这个角色的防御为15,则该角色不会受伤。此时可称为一个“生命-攻击-防御吸收”(HADa)体系。

当然,在绝大多数场景下,很少有游戏会在这种体系架构下使一个角色完全无伤,一是因为越来越多的游戏使用自动加点的方法,升级自动提升对应属性而玩家无法对此进行操作;二是可以结合等级对仅堆防御的玩法进行边际收益递减,使得玩家实际的数值提升要小于玩家所看到的提升——当然,这又需要设计一套转换的数值。对于高防御角色,现在游戏一般采用强制扣除极小伤害(如1点)等方法。以下讨论默认防御低于所受攻击,即攻击必定产生伤害的情况。

我们依然假设两个角色A(Attack= ,Health= ,Defense= )和B(Attack= ,Health= ,Defense= ),并假定A强于B,在现有规则下,伤害公式应为


前加下划线表示另一名角色。

同样类似于HA体系,有:


不难同样推导出:

联立,得:


然而这一式子难以化简为下标1的项均在左,下标2的项均在右的形式。因此需要换个思路重新进行。

我们以上一个战斗力公式为例:


应该意识到,在引入防御力这一属性后,角色每回合都能得到一个大小为 的防御,可以等效为增加额外的生命值。同时,由于回合数增加,角色总输出也得以提高。在攻击力不变的情况下,若回合数变为2倍,总输出也变为2倍,这等效于无防御时攻击力提高2倍。

因此,对生命值和攻击力进行修正,应为:



上式中, 为无防御时回合数, 为带防御后回合数。故有:


带入,得:

2020年2月11日晚修正:


修正生命值与修正攻击力都考虑了防御产生的额外回合造成的影响,这自然没有问题。然而当两个修正项相乘时,即相当于对防御收益重复计算了两次,因而,原战斗力公式在这里产生了偏差,重复计算防御收益使得防御的权重被过度放大了,原公式中右侧分式平方项应去掉平方,修改后公式见下:


很显然,当防御为0时,HADa体系退化到HA体系。且求导可得,战斗力对生命值,攻击力,防御力的导数均为正数,即不论增长的方向为哪一种,均可以提高战斗力。

不过,这里同样出现了一个很大的问题,也就是对手的攻击。简单来讲,对手造成的攻击高低也决定了这一战力数值,然而在通常计算战力数值时无疑是不可能有一个“对手”的。

一种可行的办法是虚拟一个对手的攻击值,换言之,人为规定一个 。为了防止除0的错误,虚拟的攻击值应大于防御上限。此外,观察分母可得知,防御值越接近上限,战斗力增加越快,收益越大,线性效果越差。若想取得较好的线性效果,应至少使得 达到防御值上限的2~3倍以上。

同样观察这个模型,可以发现,若一个角色仅注重提升某一个属性的属性,其收益虽依然存在,但逐渐会导致其他项的偏导数增大,最终使得提升其他属性的收益大于仅提升单一属性。

这篇文章原本刊载在我的公众号“咸鱼眼”上,20号晚上写完之后就发了。早上起来又看了看知乎上面的其他战斗力公式。

大概看了一圈,对于第一个模型其实都提出了一样的结果。这其实很好理解,所谓“活着才有输出”,角色一旦死亡,不仅之后输出为0,还会直接失败,这也是为什么第二个模型中后期防御力对战力的影响越来越大的原因——防御越高,能抵御的伤害就越多。即使仅增加一点防御,如果需要10个己方回合才能获胜,也相当于额外的10点hp,更别提如果本来无法战胜的情况下靠这10点hp多出来的一回合里能造成的额外输出了。

很多采用了线性的战斗力计算公式, 这种格式。某种程度上并没有问题,因为为了保证属性的增加能反映到战斗力上,偏导数为正这一点是必须的。但权重系数的选择很大程度上依赖于经验和模拟。并且很多时候,很难做到完美的贴合。究其原因,在于攻击与生命值——或者抽象一点,输出与续航——是相互联系的。续航越久输出的时机就越多,总输出就越高;而单次输出越高越能更快击杀敌人,击杀速度越快敌方回合数越少,因此变相延长了续航。在我看来,线性的公式很大的一个问题就在于,将两个互相纠缠的变量独立化,而提高生命值对攻击力的隐形影响被忽视了。

当然最后也应该指出,第一个公式也并不完全完美。例如两个角色A(Attack=5,Health=10)和B(Attack=6,Health=10),按照第一个计算公式,显然B的战斗力要高于A,然而让两人对打可以发现,实际情况是先手必胜。

看起来似乎花了很大的篇幅介绍了一个完全无用的模型。事实上,这是由于回合数必须取整导致的。如果我们把伤害方式和规则改成“两人碰面站着不动,按照对手攻击值的速度均匀连续掉血”,那毫无疑问B必胜。不连续的回合数导致面向连续过程的模型在这里出现了偏差,而当数值足够大时——例如A和B的生命值从10变成10000而攻击不变,则每次攻击造成的伤害足够小以至于可以近似认为是连续过程。因此,定义HA体系的偏差因子s:


其中 为敌方平均攻击力,可以采用其他水平相似的玩家或怪物的攻击力进行加权平均, 为角色生命值。偏差因子越大,证明此模型拟合程度越差。

因此若使用此模型,应该尽可能快地对生命值进行膨胀,以减小偏差因子。然而事实上,过长的回合无疑会拖慢游戏节奏。仅pve的情况下这一问题不大,因为玩家的生命值膨胀并不会影响玩家的实际体验。然而在pvp模式下,双方过高的生命值和过低的攻击力,使得战斗变成了冗长而无聊的“互相修脚”。这是在设计初期就应该竭力避免的。


作者:老咸鱼
专栏地址:https://zhuanlan.zhihu.com/p/108183307

最新评论
暂无评论
参与评论

商务合作 查看更多

编辑推荐 查看更多