文 / 李林

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

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

转载于:https://www.cnblogs.com/yzjn/p/6229818.html

暴雪战斗公式——除法公式的精髓相关推荐

  1. word公式编辑器_论文查重算公式吗 公式怎样避免查重?

    论文查重算公式吗 公式怎样避免查重?每一个毕业生想要毕业都要经过论文查重这一关,仅有通过了论文查重,才可以进入答辩.在论文检测的情况下,不少同学论文中一定会应用大批量的计算公式,且计算公式全部都是固定 ...

  2. excel输入公式显示公式_快速输入复杂的Excel公式

    excel输入公式显示公式 On Chandoo's blog, Hui is running a series of articles with Excel Tips. There were som ...

  3. 和差化积公式 和差化积公式

    和差化积公式 和差化积公式 sinA+sinB=2*sin[(A+B)/2]*cos[(A-B)/2] sinA-sinB=2*sin[(A-B)/2]*cos[(A+B)/2] cosA+cosB= ...

  4. [codeforces 1327E] Count The Blocks 打表找规律+根据规律找公式+优化公式

    Educational Codeforces Round 84 (Rated for Div. 2)   比赛人数13522 [codeforces 1327E]  Count The Blocks  ...

  5. Latex公式编号、行内公式、公式内空格、长公式换行、行内连加符号

    一.公式编号 \begin{equation} X(k)=\sum_{n=0}^{N-1} x(n)e^{-j \frac{2 \pi}{N} k n}=\sum_{n=0}^{N-1} x(n) W ...

  6. 逍遥公式验证公式软件_软件质量公式

    逍遥公式验证公式软件 您如何定义软件产品的质量? 绝对有其内在的情感成分,这意味着用户的满意程度,支付意愿,欣赏程度,积极态度等. 但是,如果我们抛开情绪,我们如何才能真正衡量情绪呢? IEEE 说 ...

  7. 如何用计算机制作公式,电脑公式怎么用

    问题一:怎样在电脑上使用计算公式计算器打开与使用方法: 1,第一种打开方法:开始->所有程序->附件->计算器. 2,第二种打开方法:开始->运行->输入calc命令,然 ...

  8. 关于word中插入公式及公式交叉引用问题

    点我进入原文 我们这里最关心的一点实际上是对公式交叉引用时候出现的将公式整体都插入引用点的现象,从这篇转载的文章中我们发现,可以通过 先键入回车分割公式与公式标号,然后将光标停在这个回车前方,使用ct ...

  9. excel输入公式显示公式_在Excel 2013中使用FORMULATEXT显示公式

    excel输入公式显示公式 There is a new function in Excel 2013 – FORMULATEXT – that lets you show the text from ...

最新文章

  1. 使用 Gitlab 进行嵌入式软件开发技巧
  2. python的沙盒环境virtualenv(一)--作用
  3. U3D中可以直接使用GL!!!
  4. 英文 电气与计算机工程学报,ei来源刊分为哪三大类?如何区别compendex和ei page one的文章?...
  5. apache 404\403错误页面跳转
  6. C# 加载C++的dll
  7. SprinBoot2.X 集成 Flowable6.6 工作流引擎
  8. 《高性能Linux服务器构建实战Ⅱ》一书纠错汇总(12月30日更新)
  9. teamviewer 破解工具 github
  10. [转]C++ 智能指针详解
  11. enum ordinal_Java Enum ordinal()方法与示例
  12. java栅栏_Java多线程 5.栅栏
  13. 中国Android应用商店汇总
  14. 针对芯片测试行业,常见stil,vcd,wgl,文件的转化,到93K,chroma,小总结
  15. SpringSecurity自定义多Provider时提示No AuthenticationProvider found for问题的解决方案与原理(一)
  16. 尼日利亚一油罐车发生爆炸 造成数十人遇难
  17. LightOJ - 1395 A Dangerous Maze (II) —— 期望
  18. C#批量转CSV到Excel
  19. 云服务器能共享文件夹,云服务器能共享文件夹
  20. web自动登录方法汇总(转自老大指导)

热门文章

  1. vue 如何判断两个数组相同_如何判断车头与障碍物的距离,教你两个办法,轻松靠墙10公分...
  2. Windows下修改Git Bash 默认路径
  3. VMware三种网络模式根本区别
  4. 处理音频文件的python模块
  5. Python不用理解进程,线程实现多任务就是这么简单
  6. 使用迁移学习不断的自我纠正神经网络
  7. openpyxl模块介绍
  8. 基于Codis的Redis集群部署
  9. linux环境搭建seafile客户端自动上传文件
  10. 活动目录之用户配置文件(转载)