• 暴雪战斗公式——除法公式的精髓


    文 / 李林

      想必一般玩过暴雪游戏的人,都会对暴雪游戏的平衡性赞不绝口。若是对其游戏数值有进一步研究的人,更会惊叹其战斗公式设计的如此精妙。暴雪的战斗公式已经成为一个流派,成为我们最广为熟知的一种除法型公式,影响着日后千千万万的游戏设计。

      对于战斗公式采用除法公式这个体系,一般的游戏设计者都不会很陌生,甚至一些资深的wower都会理解一些该体系下的结论,但实际上未必多数人都能对除法公式的精髓有着深入的了解,比如让我们来看如下的这些问题,是否都有明确清晰的答案呢。

      1. 除法公式下如何定义一个涵盖了角色所有属性量,并且可用来衡量其能力强弱的函数?

      2. 为什么除法公式中伤害减免百分比要用这么复杂一串公式?

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      3. 除法公式通常的形式和一些变种的除法公式有什么关系?

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      4. 玩过wow的很多人认为,由于伤害减免曲线随着防御增加变化越来越平缓,所以防御这个属性的收益是逐渐递减的,这个说法是正确的么?

      5. 攻击,防御,血量这些属性究竟如何影响了一个角色的能力,即不同属性提升时,角色能力如何提升?即每点属性的属性价值如何?各个属性之间的等价关系如何?

      下面我们便来逐一讨论这些问题,看一下暴雪的战斗公式究竟是如何推导出来的。他的精妙,他的美体现在何处。

      一. 能力函数的推倒

      对于非回合制的即时网游,考虑一个玩家的实力,主要看其与另外一方进行战斗时,

      被击倒的时间。(对于回合制游戏主要考虑击杀回合数)

      那么我们就来通过比较敌我双方的被击倒时间,来抽象出一个衡量角色能力的函数:

      首先,除法公式计算伤害的核心是:伤害=攻击*(1-伤害减免%),

      则:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      然后,我们比较敌我双方的被击倒时间,会有3种结果,

      即:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      将被击倒时间的具体计算公式带入,

      有:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      由于上式中各项均为正数,移动DPS参数的位置不改变不等式符号,

      即:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      至此,我们将关于己方和敌方影响战斗结果的参数分别放在了不等式的两边。那么比较两方实力强弱,即为比较这个算式值的大小,即该式为可以反映一个角色实力的函数,即:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      二. 除法公式的产生

      刚才文中有提到,除法公式伤害计算的基础其实是伤害=攻击*(1-伤害减免%),

      那么我们为什么不直接用伤害减免%直接作为角色的一个属性呢?

      原因主要有2点:

      1. 伤害减免%这个属性的值域过小,只能从0增加至100%

      2. 每点伤害减免%增加所对应角色能力的提升是非线性的

      什么叫非线性呢,首先我们来解释一下,什么叫线性。数学中类似y=kx+b形式的函数被称为线性函数,线性函数的核心在于其斜率为定值k,即y对x的变化率始终为k。在我们的公式中,以乘积形式存在的公式,即为线性公式,如 能力函数W=EHP*DPS 。线性公式的好处在于,提升每点属性所对应的能力的提升是固定的。比如例式中,当把EHP看做常量时,每点DPS的提升,对能力函数的提升始终为定值EHP,我们也可以说,每点DPS的提升对能力函数的提升是线性的。

      现在,我们回过头来看伤害减免%,显然,该值对能力函数W的提升是非线性的。由于其函数形式为幂函数,因此其具有幂函数的性质,当其逐渐增加至趋近于1时,每点伤害减免%增加带来的能力函数W的提升急速增大,以至于趋于无穷。由此我们也可以看出,伤害减免%这个值对于角色能力提升来说,其价值是逐渐增加的,伤害减免%越大越趋近于100,每增加1点所带来的提升也就越大。

      正是因为非线性所带来的属性对于能力提升的价值不恒定,难于控制,因此暴雪的公式都在极力追求线性化,由此才带来伤害减免%和防御之间的转化。那么,要如何定义伤害减免%和防御之间的关系才能使防御对能力函数的影响是线性的呢?

      首先,我们按照下式定义伤害减免和防御的关系:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      (其中f(lv)为和等级相关的一个函数,其作用稍后讨论)

      整理后可得:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      实际上这应该是多数人很熟悉的,伤害减免%和防御的关系式。将其带入能力函数中,

      有:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      此式中,防御和能力函数已经是线性关系,当HP与DPS为常量时,每点防御提升对能力函数的提升是恒定的,线性的。

      由上述讨论,我们可以看到如此定义伤害减免%和防御的意义。下面我们来讨论,定义式中防御除以f(lv)的作用。

      首先,我们来看如果没有除以一个值时,伤害减免%和防御的关系:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      此时,当防御增加时,只需增加至10以上后,伤害减免%的值迅速上升至90%以上。当伤害减免百分比达到90%以上后,每增加一点防御,所产生的伤害减免%的变化会变得微乎其微。这样玩家的面板上,伤害减免%这个值的提升变化就会很小。对于玩家来说,感受上不好,感觉不到这个值的提升,也会间接的怀疑防御这个值的作用。即使每一点防御对能力函数的提升始终是一致的,但玩家从伤害减免百分比这个角度去看,会误认为防御对伤害减免%的影响是逐渐递减的,那么防御对能力的提升是会递减的。(这种想法实际上忽略了,其实伤害减免%对能力函数的提升效果是递增的。)

      由上述讨论我们可以看出,为了使伤害减免%始终维持在一个易于认知的取值空间,故要在公式中除以一个系数,而为了能使防御无限的成长下去,该系数也要随着等级无限的增加,因此抽象出一个随等级变化的函数f(lv)。

      由于1/(1-伤害减免%)值始终要大于1,而防御/ f(lv)无法始终满足,故在关系式里加了一个1,由此定义出伤害减免%和防御的关系,即为我们之前的定义式:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      三. 除法公式的变种

      在前面我们讨论的除法公式中,伤害计算公式如下:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      在一些采用除法公式的游戏中,我们还会遇到一些变种的除法公式,例如:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      那么,这种变种公式和暴雪型的除法公式有什么关系呢?我们先将该式做一下变形,即:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      由此可清楚的看出,其实这种变种公式只是将攻击/K作为f(lv)函数而已。

      四. 有效血量EHP

      由能力函数W公式可以看出,衡量玩家实力可分为两部分,一部分和攻击属性有关,一部分和防御属性有关。

      我们把和防御属性有关的部分看作一个整体,可以把这个整体抽象成一个叫做有效血量的概念,即

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      此时,

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      对于有效血量EHP的理解,我们可以将其看作是真正衡量一个角色抗击打能力的值。正如它的名称一样,EHP是包含了玩家抗击打能力的血量,是将玩家防御和血量一体化后的有效血量。

      由上式可看出每提升1点防御值所带来的有效血量的提升是线性的,即每提升1点防御所带来的有效血量的提升的值是固定的。

      现在我们回过头来看本文开篇提到的第4个问题,显然防御增加的收益并不是递减的,而是恒定的,线性的。之所以有很多人认为防御增加带来的防御方面的提升不是线性的原因是,他们错误的认为防御提升所带来的伤害减免%的提升是非线性的(是逐渐递减的),那么防御所带来的对角色防御能力的提升就是非线性的。

      现在我们知道,衡量一个角色防御能力的应该是有效血量EHP,伤害减免%本身对有效血量的影响就是非线性的,它不能像血量一样,作为一个独立的量去衡量其对角色防御能力的作用。

      五. 能力函数的展开

      到目前为止,我们讨论的能力函数还只涵盖了血量,攻击,防御这3个属性。其实,当有更多防御属性加入时,比如抗性,闪避,格挡等,这些属性均可以以乘积的方式(以其本身或者通过一些属性转换,类似伤害减免%不合适,就要定义防御)合入到有效血量公式中。暴雪也一直在追求,将所有属性对角色能力的影响都线性化,就连像闪避这种很难线性化的属性,暴雪也通过引入敏捷,并使敏捷对闪避的关系采用分段函数的形式,来尽量保证敏捷对有效血量的线性化。

      我们已经对有效血量EHP进行了比较详尽的讨论,对于能力函数中还有一部分和攻击有关的属性我们还没有讨论,对于整体攻击属性的描述,是一个我们很熟悉的概念DPS。

      我们先以暗黑3为例,看一下当角色属性增加后DPS函数是如何构成的:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      由上式我们可以看出,这些属性均是以乘积的形式对DPS产生影响的,换句话说,这些属性对DPS的影响都是线性的,即任意属性在任何水平下,如果其他属性值保持不变,每增加一点该属性值,所带来的DPS提升是恒定的。

      六. 属性价值

      前面提到过多次线性这个概念,其最大的好处在于,线性的属性由于其对能力函数的提升保持恒定的特性,易于进行属性之间的价值比较。PS:如果非线性的话,会带来过度堆叠某种属性后,该属性的价值被放大的后果。

      下面我们来讨论如何进行各个属性价值间的比较。

      设能力函数为W(武器伤害,攻击速度,防御,生命……),那么对任意一种属性x,其属性价值,就是当其他属性不变时,每增加1点该属性,能力函数W所增加的值。由该描述我们可以看出,求一个属性x的属性价值,实际上是在对能力函数W的复合函数进行求对x的偏导数。

      如我们将能力函数简单展开为:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      那么,武器DPS的属性价值即为能力函数对DPS求导数:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      同理,我们可以得到其他属性的价值:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      由于人物属性会不断提升,所以上述各式的值也会随着各项属性的提升而增加。这样,上述各式的绝对值对我们来说意义不大。但是当游戏进行到某一个极限时,比如40级or80级,这时按游戏设计的标准人物的各个属性之间的投放比例是固定的,那么把上述各式,以某式作为标准,求出各式与其的比例,这个比例便是一个固定的值。这样我们便可以获得各个属性之间价值的换算规则。

      例如,我们以主属性作为标准式,即我们把一点主属性的价值看为1,那么:

    <ignore_js_op>暴雪战斗公式——除法公式的精髓


      以此类推,我们可以得到各个属性和主属性价值的比例。也就是1点主属性=?武器DPS=?暴击率=……

      在暗黑破坏神3的设计中,便可以首先由设计者定义出极限标准人物各个属性之间的比例,再通过在该比例下计算出各个属性间的价值换算关系,由此便可以定义出各个属性作为一个词缀的价值了。

      至此,我们基本将暴雪的除法公式体系讨论完整。暴雪除法公式之美,美在其对于对各个属性价值的精确把控,以使游戏可以达到完美的平衡;美在其通过种种公式和属性的引入,使各个属性的价值都是线性的,以使玩家的属性养成过程不会过度堆叠单一属性;美在其不断通过各种设定,使玩家的数值体验达到最优的追求。


    via:gad-腾讯游戏开发者平台

  • 相关阅读:
    遍历文件下所有文件
    访问网址(使用CDN)时 智能DNS调度 与 用户定位调度(根据IP定位)
    UV,IP,PV
    vector list deque
    mailto: HTML e-mail 链接
    freemarker 用template快速构造XML
    Oracle varchar2 length 分析
    Flex grid 复杂表头
    Oracle 动态设置SEQUENCE startwith 的值
    ssh和ssh2之间的免密码登陆详解
  • 原文地址:https://www.cnblogs.com/yzjn/p/6229818.html
Copyright © 2020-2023  润新知