最近关于数值公式的文章挺多的,我也随笔分享一点东西,仅代表个人见解,不喜勿喷。
坊间流传的反推数值,应该指的是从一款游戏的数据和系统中猜想公式、推到验证、分析设计意图、进而学习设计思想的过程。这个过程很有必要,因为在没有参考资料的情况下,这是最有效且可执行的手段。不过值得注意的是,普遍情况下,完成这个过程并不是终点,自认为洞悉了作者的设计思路,也许并非如此。我们往往从结果得到的是另外一个结果,其实我们需要的是原因,也就是为什么会出现这个结果。
今天主要谈的是暴雪的防御公式:
减伤 = 护甲 / (护甲 + f(lv))
这个公式在WOW的60时代,实际数据是:
减伤 = 护甲 / (护甲 + 400 + 85×攻击者等级)
关于暴雪的这套东西有太多的推导和分析了,比较典型的是1点护甲价值恒定、成长线性、有效控制减伤比上限等等,再高端一些的也有用高等数学知识进行演绎的。其实说的都对,得到的结论也很正确,不过暴雪在最初是通过反推设计出这个公式的么?这个公式为什么是这样? 为什么是400、85,怎么得到的?在完成反推之后,要继续追溯结果的上层,进行正推。
下面尝试性地“正推”一下暴雪的减伤公式,试图还原“正常”的思路:
假设A、B是对战双方,使用 HP×DPS/(1 - 减伤)来表示某一方的战斗能力,
其中 HP / (1 - 减伤) 表示生存能力,用大众说法它叫有效生命。(不考虑招架、闪避等高级属性)
用EHP(effective)表示有效生命,即:
EHP = HP × 1/(1 – 减伤) = HP×f(护甲)
对于EHP,设计者会想,护甲变化带来的收益效率是恒定的,也就是增加1点护甲,EHP变化是常数。(如果体验需求是护甲的收益效率先递增到某个值之后再衰减,怎么办?)
解决连续变化的最好工具就是微分方程,这里用最简单的一阶微分方程应该就可以求解,试一下。
设定 d(EHP)/d(护甲) = a×HP, 含义是护甲每变化单位量,EHP增加a×HP,其中a是个常数。
解这个一阶微分方程,很容易得到
EHP =HP×(a×护甲 +C) (C是常数)
即:
减伤 = 1 – 1/(a×护甲 + C)
由于初值 护甲 =0时,减伤必然为0,所以得到C = 1
于是无意间地得到了这样一个东西 :
减伤 = 1 – 1/(a×护甲+1)
至此,完成第一个设计目标:护甲变化对EHP的影响是效率恒定的。
不过游戏中存在等级的设定,而且希望玩家在面对高等级敌人的时候,要想达到相同的减伤效果,需要积累更高的护甲,这样一来,既能保证玩家在一个等级的横向维度上有良好的成长感受,同时也能保证纵向维度的数值追求,最关键的是为了自然合理,低等级的角色就应该经不住高等级怪物的碾压。
为了让攻击者的等级能影响减伤效果,常识性地把用f(lv)来替换a ,(f(lv)是关于lv的函数,lv是攻击者等级)。
于是有:减伤 = 1-1/(f(lv)×护甲+1)因为护甲每增加单位量,EHP变化 = HP×f(lv)
按常理推测,f(lv)一定是小于1的值,除非我们希望护甲增加1点EHP就翻倍。前面提到过,我们希望攻击者等级高的时候,EHP的变化效率要降低,也就是说lv增加时,f(lv)要减少,前期降低明显,后期趋于稳定。那么什么函数模型会满足这个假设呢?
对的,是 f(x)=1/x
构造通式得到 :f(lv) = 1/(a×lv+b)
如何求式中的a和b呢? 这个就是开篇提到的400、85如何获取的问题。
任何游戏都要设定版本的数值目标,WOW也不例外,因为是60级版本,所以我们设定2个极值:
(1,A)(60,B),A和B是版本内玩家在某种状态下的天花板数值,通过 减伤 = 1-1/(f(lv)×护甲+1) 来假设玩家状态和天花板数值, 比如当 f(lv)×护甲 =1 时,减伤 =50%,当玩家在这个状态下,假定面对60级攻击者时,需要5500点护甲,那么f(60)=5500;假定面对0级攻击者时,需要400点护甲,那么f(0)=400;很容易得到a=85,b=400 。
至此,得到 :
综上,用到了一些简单的数学知识,哪怕是微积分部分,也是最简单的一阶微分方程,看来暴雪设计师的数学水平也没高深到哪里(开个玩笑,据说平均是斯坦福的理工科硕士),不过可以确定的是,如果想做好数值,还是应该掌握一些数学知识的,可以不专,但是很多人宣扬的“小学数学“肯定是不行的。
上面的正推过程也许距离这个经典的减伤公式的诞生之路更贴近一些,从中我们也能汲取更多的思想,手段并不重要,重要的是设计目的,想清楚要给玩家什么样的节奏和体验