如何反推一个游戏
如何反推一个游戏
绪论:
由于工作原因,一篇文章常常要分3、5次才能写完,既拖沓且急就,表达效果欠佳,读者阅读也平添困难。于是在开头写个绪论,对稿子里要写的东西拟定纲目,以防止写作中断导致的思路不连贯、语义衔接失当。
下面这篇稿子将会简要的介绍:
反推一个游戏的好处
反推什么样的游戏
从战斗入手反推一个游戏
1.1.反推一个游戏的好处
反推一个游戏,代价是极大的,但仍然有人选择这样做。选择这样做的,每个人都怀有一份好奇心——是什么样的内部构造,造就了眼前的这个游戏、给了能令你心生好奇的游戏体验。
“欲诚其意者,先致其知;致知在格物。”一句“体验为王”不能仅仅是句空口号,我们游戏策划需要用丰富的知识来充实自己。而“格物”则是充实自己从而“致知”的重要手段。
反推游戏的过程,即是满足自身好奇心的过程,也是了解未知、将反推结果与先前自身的假设检验、印证的过程。在反推过程中,收获的多少,取决于你在这个过程中思考的多少。
比如,某游戏战斗相关的属性有:攻击、防御、战法攻击、战法防御、策略攻击、策略防御、统、勇、智、格挡值、闪避值、暴击值,其中策略攻击还有基于自身的成功率。游戏中,不同付费能力的用户,倾向于选择不同的攻击类型,如,压级小号或免费用户选择机械流(普通攻击)、中小R选择战法攻击、大R选择战法流搭配策士。不同付费级别的玩家,在个人整体发展策略、武将培养方式上,也各有侧重,呈现泾渭分明的状态。
(注:这里不指出游戏名称并非卖关子,而是该游戏运营的不同阶段的版本差异、各等级区间的差异,可能在上述论点上容易出现分歧造成争论。)
于是,再游戏时,对该游戏的战斗,格外关注。先从厘清战斗逻辑开始,格挡值、闪避值、暴击值是兵种的固有特性,不可培养。其中、机械流的普通攻击事件有:暴击、闪避、格挡;战法流的攻击事件有:暴击、闪避;策略攻击事件则只有成功/失败这一种事件。可见三种攻击类型,稳定性来说是递增的。相对的,从培养成本来说——机械的培养成本最低(紫武器级即可,推图即可获得,白、绿、蓝、红、紫是该游戏的装备品质)、战法流需要至少红马(商店委派——需要大量游戏币和金币)、策略流需要紫书,成本最高。
此外,游戏中,装备的强化对于伤害的提高或抵消效果非常显著,这符合减法公式的特性,但却并没有减法公式带来的付费差距那么强烈的碾压感,至少从伤害数字上,比一般减法公式更加容易接受,这固然有系统将不同付费级别玩家划分隔开的功劳,也有战斗公式中伤害下限保护的作用(约为总攻击力*10%)。但也不能排除战斗公式中仍有些别出心裁的设计,结合一些实际体验(若基础属性差距较大时,提高统、勇、智效果并不显著)可以基本判断出统、勇、智在计算时,对伤害时很可能是按比例影响的。
按比例影响的话,就有2种方式了,以机械兵种的攻击伤害举例,可能性的一种是(进攻方攻击 – 防守方防御)*Median(1+进攻方统*系数m-防守方统*系数n,%下限,%上限) 注:Median为excel中的取中值函数.另一个可能性是(进攻方攻击 – 防守方防御)*(1/((进攻方统-防守方统)*系数k+1))或者(进攻方攻击 – 防守方防御)*(1+进攻方统*系数k1)/(防守方统*系数k2+1))。两种设计各有用意,这里不深入讨论,思考到这里,其实已经对于战斗公式设计有颇多收获了,但是进一步反推可以印证咱们的推断,相当于验证一个命题的真假。一旦发现偏差,展开反思,重新假设并论证。
以下是百度知道里37玩平台客服的回答:
伤害结果= (攻守硬实力差) ×(攻守软实力差)% ×(攻击系数)
其中,
•硬实力差= (攻科技 +攻武装 +攻兵种攻击能力基值×兵阶将星%) -(守科技 +守武装 +守兵种防御能力基值×兵阶将星%)
= (攻科技-守科技) +(攻武装-守武装) +(攻兵种攻击能力基值×兵阶将星%- 守兵种防守基值×兵阶将星%)
•软实力差= ((100+攻武将属性-守武将属性) +暴击伤害加成 +攻防士气差伤害加成(攻士气-100-守士气) +(攻兵种(或战法)特色属性-守兵种防御特色属性) ±大都督以上官职伤害加成 ±阵法攻防加成 ±兵力加成<数量或比例?>)%
•攻击系数= 兵种普攻(或战法类型)攻击系数
可以看到,是前面列出的第一种可能性(其实这个回答并不正确,将星其实是固定值增加基础属性的)。
至此,我们至少知道了这样的体验,需要一段怎样的伤害公式、装备如何投放,如果我们想改变某个局部的体验,应该动哪些地方。
反推的结果并不仅限于数值如何设定,理想的反推结果应该是一个完整的思考过程——数值设定、相关系统规则支持、相关的资源投放、量化/平衡思路,以及他们怎样对体验产生了影响。
1.2. 反推什么样的游戏
子曰:三人行,必有我师焉;择其善者而从之,其不善者而改之。反推任何游戏都能多少有些收获,但如果能更有针对性的去反推,能更精确有效的完善自身的知识理论体系。
选择反推的游戏对象可以从以下两点考虑:
1.你着意研究的点
2.游戏的反推难度
首先针对咱们关注的、局部有亮点的产品进行精细反推,比如:暗黑2的掉落机制及mf值对掉落的影响、WOW装备等级和属性数值存在怎样的关系、某收入奇高的游戏的付费点分布及售价、炉石传说的卡牌花费、属性、卡牌品质的量化思考。
其次要考虑的是反推的成本,应尽量选择数据公开的较全面、数据采集相对容易的游戏进行反推,最好也是自己熟悉的游戏,大部分人可以从DOTA、LOL或WOW开始,一方面战斗属性及其效果都有较清楚的展示,另一方面各网站也有相关的数据库供查询。
个人看法:一般来说减法公式比除法公式的反推难度更大,背后的设计思想也更难以把握;年代久远的游戏,设计可能更纯粹(2000-2005年是个网络游戏百家争鸣的时代)
1.3.从战斗入手反推一个游戏
在大部分游戏中,核心玩法都是围绕着战斗系统设计的,下面以一家之言,介绍反推一个游戏战斗设计的过程,仅供参考。
我想研究一个古老点的游戏,原因正如前面所说,我更想看到的是设计师更纯粹的一些思考痕迹。
之前《千年》运营的时候,正上着学,千年不出点卡,学生党买月卡很不划算。饶是如此我也沉迷其中,每周末跑网吧建个号玩2天。苦练杀牛功夫,玩的最好的周末号,在2天内杀牛赚钱学了血手印和金钟罩。
血手印、噬魂枪、金钟罩当时是大陆服务器的三大绝世武功,在PK时血手印和噬魂枪能克制大部分武功。虽然相对少点,但也确实有武功能克制它们,印象中能克制血手印的有种武功天地人拳。除了这三大神功,其余武功也分别有克制和被克制的武功。
这次反推《千年》的战斗设计,就是想搞清楚,这种克制关系是怎样实现的,有可能单纯的数值驱动就能实现循环克制吗?亦或者背后还有隐藏的武器生克关系?
| 打开人物信息栏(快捷键“Alt+A”)可以查看人物属性。各属性代表含义如下 |
【年龄】 | 角色的年龄值,在线时间越长,年龄越大。 |
【修为】 | 角色的修为值,修为值越高,修为境界越高。(修为值计算方式为 |
|
|
【活力】 | 即角色血量,血量小于0人物死亡。 |
【内功】 | 即角色内功值,内功值小于0则无法使用攻击性武功。 |
【再生】 | 死亡时即可增加,再生越高人物复活时间越短 |
【耐性】 | 受到高伤害时候增加,耐性越高修为境界盾的抵挡伤害越高 |
|
|
【速度】 | 速度值越低,攻击速度越快。 |
【命中】 | 即命中率,命中越高,攻击击中目标的成功率越高。 |
【闪躲】 | 即躲闪,闪躲值越高,闪躲对方攻击的几率越大。 |
【恢复】 | 恢复值越低,受到攻击后还手速度越快。 |
|
|
【身体攻击】 | 攻击力即破坏力,数值越高,攻击力越大。 |
【头部攻击】 | 数值越高,攻击其他玩家时,降低其头部活力越多。 |
【手部攻击】 | 数值越高,攻击其他玩家时,降低其手部活力越多。 |
【脚部攻击】 | 数值越高,攻击其他玩家时,降低其脚部活力越多。 |
【身体防御】 | 数值越高,受到攻击后减少的活力越少。 |
【头部防御】 | 数值越高,受到攻击后减少的头部活力越少。活力越小,准确率越低,当头部活力小于20%时候,无法更换武功。 |
【手部防御】 | 数值越高,受到攻击后减少的手部活力越少。活力越小,攻击力越低。 |
【脚部防御】 | 数值越高,受到攻击后减少的脚部活力越少。活力越小,闪躲和恢复越低。 |
以上是某个类《千年》游戏的人物属性说明,大体与千年一致,略有简化(差异处暂且不提)。战斗时,锁定攻击目标进入攻击状态后,己方角色向目标发动攻击,攻击力和攻击速度取决于自身基础值和武功、装备。
相关的计算公式有:
角色总攻击力=角色基础攻击力+当前武功攻击力+装备攻击力 ( 式 ① )
注1:角色有4“血条”,第一是活力,相当于生命值(下图右下角)、另3个分别是头活力、手活力、脚活力,功能参见上文属性说明。
注2:式①对作用于活力、头活力、手活力、脚活力的身体攻击、头部攻击、手部攻击、脚步攻击均适用。
注3:下图中的破镜是角色的武功境界,武功境界也可以增加攻击力和防御力,为了更针对主题,这里暂不考虑这些,可以将其舍弃原因是,令我们好奇的武功相互克制,在没有境界时就已经有很好的效果。
角色总防御力=角色基础防御力+当前武功防御力+装备防御力+护体防御力 ( 式 ② )
对敌伤害=自身的角色总攻击力-敌方的角色总防御力 – 敌方耐性所产生的抗击打能力 ( 式 ③ )
注:网上找到的公式原文输入是这样的:人物所受伤害=(对手装备攻击力-自身装备防御力)+(对手武功攻击力-自身护体防御力-耐性所产生的抗击打能力) …
虽然这次很幸运的能从网上找到公式,但大多数情况下,网上找不到可信的公式,这种情况下,只能自行反推。
反推过程虽然繁琐但方法得当的话,难度并不大:
1.3.1. 了解战斗逻辑
尽可能了解战斗逻辑、弄清楚属性的统计过程、并列出战斗属性列表。今天隔壁项目组同事扔给我一表格,是个卡牌类的游戏,表格有英雄相关属性,有一列数据名称是“宝具”,不仔细点看,很容易当做装备,其实则是英雄突破后新获得的被动技能,不可拆卸。比如,绿关羽进阶成紫关羽之后,自动装备了不可拆卸的青龙刀,增加了若干点攻击力。如果在这里对属性统计过程产生误会,对卡牌属性量化思路的反推,可能会带来额外的困扰。
1.3.2. 挑选战斗
一般来说,应当找一个可反复尝试,且不会随多次进行产生额外变化的战斗进行数据采集。比如,之前玩《金庸群侠传之苍龙逐日之正邪谁判》,练功用的小和尚,被打的多了会升级,血量防御攻击都会随之提升。
相应的,己方也要排除角色升级、技能熟练度满了升级等因素。也要避开游戏的维护更新,否则难以排除更新带来的数据差异。
另外,有不少游戏,PVE的战斗中,怪物是没有防御力的,这对于推算和比较各技能强度比较有利,但是却很难推出攻击与防御在伤害计算时发挥了怎样的作用。
若条件允许可以用自己的2个号PK。
1.3.3.确定范围
比如攻击浮动、暴击、格挡、招架、护盾等等。
先观察属性面板攻击力数值是否有上下限。当前大多数游戏已经舍弃了将攻击力属性分为攻击力上限和下限的设计,而是只保留攻击力数值,在计算伤害时,对最终伤害进行一次随机的%修正,通常这个修正区间是[0.95,1.05],通用公式是[1-r%,1+r%],如果运气不好,可能需要多次采集数据计算出这个随机修正区间。
然后是暴击、目前很多游戏暴击时的修正倍率是可以从属性面板查看到的;而无法查看到确切暴击的游戏,也往往是个固定值的暴击修正,比如怪物猎人系列的会心一击是125%伤害、负会心是75%伤害。
有些游戏如WOW格挡、招架等事件也对伤害有修正。
最后,还有等级/战斗力压制情况需要确认。
1.3.4. 采集数据
数据应格式统一。在伤害发生时的面板攻击力(总)、面板攻击力(躶体)、装备攻击力、技能被动加成,以及当前的各种伤害修正值。虽然严格来说这些值应当分别列出,有些游戏在伤害计算时,部分来源的某项属性,比如装备的攻击力与其他来源的攻击力效果有差异;但大多时候我们只需要记录面板的总攻击力、对方的总防御力以及其他伤害修正相关的属性值即可。
下为数据记录示图:
1.3.5. 设计反推
数值反推相比起统计学的数据分析,更像是城池的防守,防守方需要假设进攻方可能采取的一切手段,逐一拆解,将设计思路还原。
以下是一个升级经验的配置表:
等级 | 经验 |
1 | 235714 |
2 | 257143 |
3 | 278571 |
4 | 300000 |
5 | 321429 |
6 | 342857 |
7 | 364286 |
8 | 385714 |
9 | 407143 |
10 | 428571 |
11 | 471429 |
12 | 514286 |
13 | 557143 |
14 | 600000 |
15 | 642857 |
16 | 685714 |
17 | 728571 |
18 | 771429 |
19 | 814286 |
20 | 857143 |
21 | 921429 |
22 | 985714 |
23 | 1050000 |
24 | 1114286 |
25 | 1178571 |
26 | 1242857 |
27 | 1307143 |
28 | 1371429 |
29 | 1435714 |
30 | 1500000 |
31 | 1585714 |
32 | 1671429 |
33 | 1757143 |
34 | 1842857 |
35 | 1928571 |
36 | 2014286 |
37 | 2100000 |
38 | 2185714 |
39 | 2271429 |
40 | 2357143 |
41 | 2464286 |
42 | 2571429 |
43 | 2678571 |
44 | 2785714 |
45 | 2892857 |
46 | 3000000 |
47 | 3107143 |
48 | 3214286 |
49 | 3321429 |
50 | 3428571 |
用Excel趋势线,二项式拟合得到如下方程。
相关系数R=1,可以说已经非常完美了,继续在C列按照拟合函数输入公式,得到一列新的数据:
从图中看到,误差还不小。对于通常说的数据分析来说,这样已经足够了,但是对我们反推设计思路并无帮助。(有兴趣的同学可以对这里进行深入思考——为什么会有误差)
上图是拟合数据列的回归方程。
可见,趋势线虽然能体现自变量和因变量的关系,但是有时并不能关于,我们得考虑换个思路:
看到B4有个值非常整齐,我们在C列输入公式=A2/$B$4,为了再观察这列结果的差,我们在D3输入公式c3-c2,得到:
现在至少能看出这是个分段的等差数列——1~10级的差是0.07142857,而这个值等于1/14。题外话,142857是走马灯数,虽然不知道用在这有什么用意,但凑巧知道这个掌故的话一下子能把1/14找出来。虽然用这里论证不是很有说服力,但平日积累之功对设计反推确实有大裨益:
比如常用的战斗公式:
减法:
伤害=Max(攻击力*10%,攻击-防御)
除法:
伤害=攻击力*1/(1+k*防御力)
其它:
伤害 = 攻击力*攻击力/(攻击力+防御力)*2
等等..
还有常用的函数略过。
1.3.6. 反推成果例举
《千年》的反推还完成,因为暂时没考虑新项目朝着这个方向,所以动力略微不足,进度缓慢。
自《千年》推出门武之后,这些武功数据基本上都可以很容易反推出来了,现在网上找找就能得出上表的数据。
门派武功在设计时候,有以下的约束条件(网上也能找到的):
速度x与攻击设计值y之和为100
实际速度=73-X*0.6,得出数值在13~72之间,小数舍去。数值越小,速度越快;反之越慢。
实际攻击=(275+Y*6.9)*1.25,得出数值在351~1195之间,略有偏差。
恢复m与闪躲设计值n之和为100
实际恢复=120-m,得出数值在21~119之间,数值越小,恢复越快;反之则越慢。
实际闪躲=n*0.6,得出数值在0~59之间,小数舍去。数值越小,闪躲的机率越低;反之则越高。
三攻和防御:
取值公式:攻击(X)头+手+脚+防御(Y)身体+头+手+脚=228 X,Y的取值范围:10~70
实际攻击=203+X*5.1,得出数值在254~560之间,略有偏差。
实际防御=3+Y*2,得出数值在23~143左右,略有偏差。
反推出来的一些设计思路:
- 并没有哪个武功能永远获得优势,这是攻击和速度的设计公式决定的:当防御力足够高时,攻击力高的占优势;反之,当防御力较弱时,速度快占据优势,这是一个动态平衡。
- 闪躲按比例的延长了自身的生存周期、恢复则按比例的减少对手的生存周期(恢复好的武功相比起来有更多的额外攻击机会,即反击)。
- 在一个模块的平衡基础上,垒上另一个平衡模块。比如1 的攻击和速度的动态平衡基础上,加上了闪躲与恢复的平衡。
- 在3的基础上,又添加了三攻和防御的平衡。
- 相同武器类型的武功、身体防御相同,以拳法为例:
- 血手印和噬魂枪的设计也遵从速度x与攻击设计值y之和为100以及恢复m与闪躲设计值n之和为100。但是防御力却相较同类别武功高出许多——拳系防御98、枪系41。
下图可能对于了解防御力在武功生克时发挥了怎样的作用,能更清晰的展示,也可以手动解开相关方程之后,用Excel绘制:
横坐标x表示武功A的攻击设定值,纵坐标y表示武功B的攻击设定值。该图绘制的是
((275+x*6.9)*1.25-def1)/(73-(100-x)*0.6)/(((275+y*6.9)*1.25-def2)/(73-(100-y)*0.6))-1(式⑤)
即武功A相对武功B的伤害优势%,黄绿分界线是表示双方伤害相当的等高线。对照色阶,大于0的区域表示的是武功A获胜;反之是武功B获胜。红点坐标(30,70),表示的是无名拳法VS无名槌法,看落点拳法略逊一筹。
调整式⑤,给双方各增加50攻击力,拳法获胜:
于是,最终达到一个效果,各武功的生克、平衡关系,可以通过投放不同倾向的装备调控,而不需要削弱或加强武功。
附,Mathematica运行语句:
DynamicModule[
{d1 = 98, d2 = 23, pts = {30, 70}},
Deploy@Column[
{
Row[{Text[Style["Def 1 ", Red, 16]],
Slider[Dynamic@d1, {0, 300, 1}]}], Dynamic[d1],
Row[{Text[Style["Def 2 ", Cyan, 16]],
Slider[Dynamic@d2, {0, 300, 1}]}], Dynamic[d2],
Dynamic@ContourPlot[
(((275 + x*6.9)*1.25 - d1)/(
73 - (100 - x)*0.6))/(((275 + y*6.9)*1.25 - d2)/(
73 - (100 - y)*0.6)) - 1, {x, 1, 99}, {y, 1, 99},
Axes -> True, Frame -> False, Background -> None, Mesh -> 10,
ColorFunction -> "BrightBands"
(*RGBColor[1-1.25#,1-2#,1-2#]&*),
PlotLegends ->
BarLegend[Automatic, LegendMarkerSize -> 180,
LegendFunction -> "Frame", LegendMargins -> 5,
LegendLabel -> "色阶"],
AxesLabel -> {x, y}, ImageSize -> Medium,
BaseStyle -> {FontFamily -> "Helonia", FontSize -> 16},
Epilog -> {Red, PointSize[Large], Point[pts]}
]
}, Alignment -> Center, Frame -> True, FrameStyle -> Gray
]
]
1 / 17