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

文 / 李林

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

  对于战斗公式采用除法公式这个体系,一般的游戏设计者都不会很陌生,甚至一些资深的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-腾讯游戏开发者平台

时间: 2024-08-24 13:16:55

暴雪战斗公式——除法公式的精髓的相关文章

游戏伤害算法之除法公式(3)

公式原理:伤害=攻击力*攻击力/(攻击力+目标防御) DMG=ATK*ATK/(ATK+targetDEF) 使用情况: 这个公式是魔兽世界的公式,免伤率变成一个动态的结果,跟攻击方的攻击力和防守方的防御同时相关. 如图所示,红线代表伤害关于攻击力的函数曲线,橙黄色代表伤害关于防御力的函数曲线.从这两个函数分析得出,当攻击方攻击力大于防御方防御力时,曲线接近直线既每点攻击力带来的伤害增益为1点.当防御方小于攻击方攻击力时,曲线接近直线既从普遍情况来看,每点防御力带来的伤害减少为0.5点.所以使用

POJ 1845-Sumdiv(快速幂取模+整数唯一分解定理+约数和公式+同余模公式)

Sumdiv Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1845 Appoint description:  System Crawler  (2015-05-27) Description Consider two natural numbers A and B. Let S be the sum of all natural d

代做公式选股、同花顺选股公式调试、猎庄主图指标公式指标公式-同花顺公式

原理解析:当满足条件(收阴线)时,在最高价和最低价位置之间画柱状线,宽度为0.5,0不为0则画空心柱.,COLOR008800当满足条件(收阴线)时,在最高价和最低价位置之间画柱状线,宽度为0,0不为0则画空心柱.,COLOR00FF00当满足条件(收阴线)时,在收盘价和开盘价位置之间画柱状线,宽度为4,0不为0则画空心柱.,COLOR008800当满足条件(收阴线)时,在收盘价和开盘价位置之间画柱状线,宽度为3.5,0不为0则画空心柱.,COLOR009900当满足条件(收阴线)时,在收盘价和

POJ1265:Area(多边形面积公式+pick公式) 好题

题目:http://poj.org/problem?id=1265 题意: 题目解析: #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> #include <queue> #define inf 0x3f3f3f3f #define eps 1e-9 typedef long long ll

游戏数值策划属性篇(三):战斗公式的设计

GameRes游资网授权发布 文 / 张锋 在战斗设计中需要考虑战斗的目的,例如,野外打怪的设计的主要目的是玩家完成任务和挂机,部分野战需时较长让玩家有时间发生冲突,设计中尽量简化玩家的操作,通过一些设计给玩家新鲜的感受. 战斗设计的几点要素: 战斗规则 攻击方:攻击发起方: 防御方:被指定为攻击方,被击方: 受击方:一般情况下受击方=防御方,发生援护时,援护方=防御方 判定互斥 战斗状态以圆桌展开,相级属性互斥处理(如果有的话 反击.躲闪.格挡等不能并发) 红名规则 例如,打怪可减少红名时间,

排列组合公式

今天在写一个算法的时候用到了排列组合,突然感觉不熟悉了,于是自己搜索了下, 重新复习下,把笔记记下来,便于以后复习. 第一,排列 1)排列的定义,就是指从给定n个数的元素中取出指定r个数的元素,进行排序 2)排列公式 3 公式解读, 总长度为r,第一个人有n-0种选,第二个有n-1种,,,,最后一个有n-(r-1)种(为什么是减去(r-1) 因为到第r个人的时候,发现自己前面有r-1个人已经消耗了r-1个选择了,自己的选择余地变成n-(r-1),这和第一个人发现前面有0个选择已经消耗是一样道理)

使用Axure RP原型设计实践05,了解公式

本篇体验公式的使用,一般出现值的时候就可以使用公式,公式可以使用全局变量也可以使用局部变量,在Axure中使用公司有一定的语法. 先创建2个全局变量. 向页面中拖入Rectangle部件,给它的OnClick事件编辑用例: 让其显示两个全局变量的和.注意:[[a]]+[[b]]这样写是不可以的. [[]]里面可以进行计算,设置条件,还可以插入其它值.写在[[]]之外的都被当作是字符串. 预览,点击矩形区域显示2个变量的和. 如果是设置值事件,如下写法分别返回的结果是: ● [[1>2]] fas

c语言详解  蔡勒(Zeller)公式计算某一天是星期几  极其方便

—— 蔡勒(Zeller)公式 历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和一些分段计算公式),其中最著名的是蔡勒(Zeller)公式.即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 公式中的符号含义如下,w:星期:c:世纪-1:y:年(两位数):m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1.2月要看作上一年的13.14月来计算,比如2003年1月1日要看作2002年的13月1日来计算):d:日:[ ]代

五猴分桃通解公式-敬献给诺贝尔奖获得者李政道博士

摘要:"五猴分桃问题"是一个中.外非常有名的趣味数学难题.研究这种类型题的简易计算方法曾困扰住了一些大物理学家和数学家.李政道博士在中国科技大学讲学时也特意提到此题, 本文通过对该问题的分析,推导出了能求解所有这种类型题的最简易通解公式 y=a(a/m)n-1-db/c,以及它的姊妹公式: y=[ka(a/m)n-1-db]/c,以及这两个公式有解和无解的条件,使这个问题得到了较园满的解决. Summary: "Five monkey peach assignment pro