文/彗星尘
从根源上,人很难想象自己没见过的东西,有些观点认为人根本无法想象自己没见过的东西,这个论断是否绝对准确不是我们要讨论的,我们只需要达成一个统一认识即可:对于几乎所有人而言,在绝大多数情况下,所谓创新,都是将已知的各个细节元素打散,归类并分析,然后重新组合的过程。
在此基础上,我们谈技能创新,那么第一步需要做的,必然是将技能本身拆分一下,然后加以分析和归类,最后组合;
那么,我们把一个技能从开始释放到效果结束的过程,拆分成四个阶段:
1、 释放阶段
2、 条件判断阶段
3、 效果阶段
4、 状态改变阶段
其中,前面三个阶段可能会受状态的影响,因此假设玩家具备几个基础状态是必要的。
状态
先假设几个必备的状态,其中某些状态在程序的实现上未必是一个单独的状态机(如减速),可能只是正常状态带了一个效果而已,但我们在设计时不应该考虑这点,这个需要在跟进功能的时候才需要与程序商讨的事情;假设玩家有三种基础行为即移动、释放技能、普通攻击,那么根据这三种基础行为的受限与否,定义出所谓的“玩家控制状态”,用来方便我们设计;“玩家控制状态”显而易见可以分为8种:
当然,并不是每一种“玩家控制状态”在游戏内都会用到;也有可能游戏内的每个状态会对应到同一类“玩家控制状态”,如眩晕和死亡,显然不是同一个状态,但玩家都是处于所有行为都受限的状态下;
1、 普通——玩家自由移动,自由释放技能,自由攻击
2、 失明——玩家自由移动,自由释放技能,攻击受限(无法攻击或强miss)
3、 沉默——玩家自由移动,不能释放技能,自由攻击;(多说一句,这里为什么不像限制普攻一样做成“有几率地让技能无法释放或无效果”?这个效果本身也并不是所有游戏里都不会出现,然而通常会做成娱乐模式的效果;正常情况下,主动技能会需要即时反馈,而“有一定几率无法释放技能或技能释放无效果”对于双方来说都是很差的感受。)
4、 残废——玩家自由移动,技能和攻击都受限;
5、 减速——玩家移动受限,自由释放技能,自由攻击;
6、 定身——玩家移动受限,自由释放技能,攻击受限;
7、 封印——玩家移动受限,释放技能受限,自由攻击;
8、 眩晕——玩家不能移动,不能释放技能,不能攻击;
9、 死亡——玩家不能移动,不能释放技能,不能攻击;
这里有一个有意思的事情:眩晕和死亡有什么区别呢?是不是一个英雄眩晕了比如说2分钟,就相当于阵亡了呢?其实这是因为我们在前面讨论的时候有一个玩家的被动行为没有参与到列表中,即“能否吸收技能效果”、“能否吸收伤害”,这个跟“能否提供视野”是一样的——也许会有特殊技能针对这两类行为做一些事情,但确实太少了,给玩家提供新的、可选择的行为模式确实非常值得思考,但我们还是先不要考虑过于复杂的情况——因为显然每增加一种因素,组合的可能性就是翻倍的;在实际设计中,我们会期望尽可能地把种种情况罗列出来,但为了表达方便,比较少出现而且又比较复杂的情况这里就先不讨论了(其实就是懒得给各种状态取名……实际设计的时候甚至可以用二进制命名,如状态101对应“沉默”状态,这样完成设计以后统计一下总共用到了多少个状态然后分别取名就好了)。
当然,除了受限之外,也有很多技能是对自己三种基础行为的强化;当然对应的强化也有8种这里不一一列举;另外对行为的强化和削弱可能也会有一些组合如强化攻击效果但限制移动、提升技能但限制普攻等等,也不赘述;提升一种属性降低另一种(如提升攻击速度但降低防御力)数值向效果与行为无关,这里也都不再进行讨论。有意思的是降低或扩大视野这个效果,虽然本身与玩家行为不挂钩,但实际游戏中可能会对战局有非常大的影响,甚至不止局限在战术层面,不少情况下甚至对整体战略都会产生影响,因此这类技能在设计时也是需要特殊考虑的一种情况。(多说一句,其实这个跟死亡效果结合到一起会产生非常有意思的影响,比如某个英雄死了之后继续提供视野等等)
技能释放
技能按玩家操作划分,可以分为三类:不用点的,点一下的,点两下的(手机上一般是点——拖,松手=释放);为什么这样划分而不是用看上去更科学一些的“指向性、非指向性”等方式来划分呢?事实上,我们在设计技能具体数值的时候确实会用到这类划分方式,设计技能机制的时候,我们更加应该关注的是“玩家操作的便捷性”,举一个简单的例子,如果一个英雄,其所有技能都是需要“点两下(或者点击技能——拖动选择方向/区域——松手时释放)”,那么毫无疑问,在数值平衡的基础上,无论最终技能效果和数值设计成什么样子,这个英雄都必然是一个对操作和意识要求比较高的英雄(预判方向/区域、对技能释放时机的把控),所以在前期设计的时候,用这种简单的方式来划分技能释放能够更接近我们想要的最终结果。
这样就很容易简单列出这几类技能的特征:
不用点的:
- 条件自动释放和被动类别两种情况;
- 条件可能包括:任意敌人/区域内满足某条件的敌人进入某区域(如HP低于X%) /大于一定数量的敌人达成某种条件等等等等,作用目标可能是自身/满足条件的敌人/生成的某个区域等等
需要点一下的:
技能需自动选择目标(包括索敌、自身作用范围),自动生成位置/方向/范围等
需要点两下的:
需手动选择方向/选择区域/选择目标
这样罗列下来发现一个非常简单的规律:所谓“自动/点一下”的技能,本质上是把“点两下”的技能,将其释放条件和作用目标拆分开,分别让程序按照某种规则进行判断而已,于是我们很容易就能想到:如果想要提供新的游戏体验或游戏行为,可以从释放条件与作用目标两方面做文章,与释放模式进行组合后必然会得到极多的可能性,诸如探测到有40%以下HP的英雄进入到某区域后,立即在其位置召唤一个传送门等等。
条件判断
我们在技能描述的时候,通常会把“条件判断”和效果放在一起告诉玩家,但作为设计者,我们一定要清楚这是两个东西,一个只是用来进行判断,另一个是用来让敌方/自己的某些属性/状态进行改变的。
条件判断,或称“buff”阶段,这个是最容易做出花样的部分;设计时需要有一个思路:我们往玩家身上丢的是一个/数个带效果触发器,这个触发器可能会根据各种情况触发相应效果;
常见的条件:
- 加上时(带条件)触发,移除时(带条件)触发,循环(带条件)触发;
- 进入某状态时(条件)触发,离开某状态时(条件)触发;
- 进行某行为时触发,某效果生效时触发;
……
等等等等,这个要一一列举就实在太多了,另外buff的加上与移除本身也可以加上一些判断条件,如施法者停止施法动作时移除等等,具体的触发效果和触发参数可以直接从星际争霸II编辑器内“触发器”一栏里所有罗列的状态,基本在设计技能时都可以用得上,这个罗列起来实在太多了不再赘述;实际设计时需要注意的仅仅是区分哪些触发逻辑对于玩家来说理解成本/操作成本过高,到底高到什么程度等等,可以说,技能上80%的新感受都是由效果触发条件来决定的。
效果
一般来说,有很多新手在设计技能时会投入非常多的精力尝试在效果上做文章,而事实上玩家缺经常不买账,这是为什么呢?这个我们后面会说到
游戏中常见的效果分为几类:
- 改变玩家的某些属性(如HP,攻击力,防御力,移动速度,视野)等等;
- 强制切换玩家状态(眩晕、沉默);
- 强制位移(推推棒,强制回城,传送门);
- 令其他效果无法生效(针对效果的);
- 最终呈现出来的技能效果,基本都是上述几种模式的组合;
这也就解释了,为什么尝试设计新技能效果时,总会有种“吃力不讨好”的感觉;本质上是因为效果无论怎么设计,总共的排列组合总是有限的;如果想要做出差别来,只能利用多个效果叠加,如“强制传送回城并沉默直到HP回满”等等,但是即使这样做,所能做出的效果总数也非常有限;对于玩家来说,“提升自己攻击力并持续造成伤害”和“提升自己攻击速度但防御力下降”两个效果在实际应用中确实可能有很大区别,但在自身行为上并没有本质上的差异——都是提升输出能力降低生存能力,二者事实上还是属于同类效果,只是数值偏向有所差异;事实上,如果按照上述的思路分析一下就很容易发现,即使以技能设计见长的Moba大作,如Dota、LOL、王者荣耀、风暴英雄等等,在“效果”这个点上也没有做太多的花样。
不是结论的结论
综上,我们把技能拆分成了四大块,不过整个文章读一遍下来,好像并没有提到新技能怎么做,怎么能够让玩家耳目一新啊?
非也,技能设计是一个整体化的过程,零星地进行单纯想法上的创新固然在某些时候会有“灵光一闪”的感觉,但是整个游戏的多样化是不能建立在“灵光N闪”的基础上的,更何况实际制作时还需要考虑平衡性和玩家的理解成本;
而利用这样的思路拆分后再组合成技能,首先能够保证游戏内所有技能在宏观上是处于同一体系下的,其次多样性也有足够的保证。
当然,关于技能多样化和平衡性的问题是永远不可能有定论的,即使市面上成功的大作也根据实际情况不断进行调整;如果我们假设有一个“终极理论”能够完美描述技能设计方案的话,那我们用这样的方法,希望能够窥得其中一角。
从强化到技能这里讨论一点干货吧。
先从强化开始,之后我们再说为什么会从这里扯到技能上。
假设一种情况:对某装备进行强化,可能产生三种后果:掉级,不变,升级;;这里我们设计时一般会关注几个点:期望次数,经过N次强化行为后玩家处于某个特定状态的概率,还有期望成本。
简单做法
期望次数有个简单的做法:
假设现在强化等级是n(n>0),强化成功的期望次数是E(n),强化行为之后,强化等级可能掉级变成0,1,……n-1,n,n 1,概率分别记为P(n_0), P(n_1),……P(n_n-1), P(n_n), P(n_n 1);
那么,由期望的性质,我们可以列出这个方程:
E(n)=P(n_n 1)*1 P(n_n)*(E(n) 1) P(n_n-1)*(E(n) E(n-1) 1) ……
对于绝大多数情形,强化等级不会特别高,而且我们通常不会让装备失败就掉落底层,也就是说大多数情况下可能从第四项开始就都是0了,因此对于绝大多数强化的情况,设计时可以停在这一步,然后把E(n)当做方程来解就可以了,而且这个还可以直接在Excel写成公式下拉直接得到结论,很便捷;
不过显然我花了这么多时间来输入如此多的字母并不是想停在这里的,而是想得到一个更普适的结论。
我们记S(n)为从强化0到强化n 1的总次数
则有S(n)=E(n) E(n-1) ……E(1),因此E(n)=S(n)-S(n-1)
然后代入并化简可得
S(n)=1/(p(n_n 1))*(1 S(n-1))-Σ(i=2 to n)(P(n_i)*S(i-1)),n>0
这样,我们就有了一个普适的公式,然后直接写个VBA或者Matlab就能运用到所有情况了。
状态矩阵的构造
上面的办法运用了期望的数学性质,所以相对简单;如果不是这样的话,我们可能需要运用到矩阵。
对于一个游戏来说,强化显然是有上限的,设这个上限为N,为了方便写下标,我们不考虑强化=0的情况直接从1开始(对,我就是这么懒)。
对于强化为m的状态来说,进行一次强化行为,可能变成强化1~N的几率分别为Pm_1~Pm_N,假设记为Pm=[Pm_1 Pm_2 …… Pm_N];
这样我们把所有强化状态都列出来,就能构造出一个N*N的矩阵了,这个矩阵的第m行表示对强化为m的状态来说,进行一次强化行为,可能变成强化1~N的几率;第m列表示强化1~N的装备进行一次强化行为,可能变成强化m的几率。
参照矩阵乘法第x行第y列的计算方式,很容易知道:如果初始状态是x,进行k次强化后达到状态y的几率,其实就是把这个矩阵与自身相乘k次,然后第x行y列对应的元素值。
于是,对于任意初始状态,强化N次后停留在每个状态的几率就这样直接解出来了……
一个显而易见的解法
显然N次以内玩家达到某个特定状态的概率也很容易求了:
设P(n-1),Pn,P(n 1)对应掉1级、不变、升1级三个状态,为了讨论方便假定只有这三个等级(更多情况同理,只是矩阵变大了。)
首先列出一步转移概率矩阵
因为求的是k次以内强化到n 1的几率,所以强化到n 1就不用再变化了,所以令初始矩阵等于
然后让这个矩阵取自身的k次幂即可,同样的第x行第y列就是经k次强化行为以后,初始状态由x变为y的概率。
显然,k次强化后的概率矩阵取初始状态行点乘等级向量就是经过k次强化后的期望等级了。
由状态转换矩阵求期望
我们已经知道状态转换矩阵的n次幂就代表结果,那么期望怎么用矩阵求呢?
其实跟上面的办法很接近,只不过在上一个问题中我们设定“强化k次或达到强化n 1”停止,这里的条件就是“达到n 1”。
用矩阵来解确实麻烦一些,尤其与第一段“简单做法”比起来。不过办法还是有的。
如果我们假设强化到目标等级总共需要k次的话,也就意味着前面k-1次都未达到目标等级;
我们假设求的从x强化到y,设状态矩阵为P,那么就得构造一个矩阵P’,P’的第Y列=0,然后P’^(k-1)*P就是最终的状态矩阵,其中第x行第y列元素就是“从x强到y共强化k次”这一事件发生的概率。
为了数学上方便,E为单位矩阵的话,Ey就是令单位矩阵的第y列=0;同理Ix设为1行n列的向量,第x个元素为1其余均为0、Iy为n行1列的向量,第y个元素为1其余均为0。
这样,从x强到y共强化k次的概率就可以用数学语言表示为:Ix*(PEy)^(k-1)*P*Iy
那么,期望次数就相当于上述概率乘以k,然后令k=1到无穷大求和了;
期望次数用Exy来表示的话,就有Exy=Σ(k=1 to ∞)(k* Ix*(P*Ey)^(k-1)*P*Iy)
当k趋近于无穷大时,有Exy=Ix*(E-P*Ey)^(-2)*P*Iy;
多说一句结论,如果每个等级对应的消耗不一样的话,用成本矩阵点乘各个等级的期望次数可以得到消耗矩阵,设成本矩阵是c,x到y的总消耗是Cxy,直接说结论:
Cxy=c·(Ix*((E-P*Ey)^(-1)*P E)*Ey)
扯远点到技能
说到底,这玩意跟技能有啥关系?
我们先回想一下上一篇碎碎念中提到的,我们设计时需要假设的玩家状态,这个是设计的第一步;但是到第二步,也就是实际设计技能数值时会发现,一个技能造成的可能状态不止一个,常见的:眩晕技有可能让玩家进入眩晕,也有可能直接造成死亡;还有一些类似蓄力的技能,可能随着蓄力时间的改变,其效果也会有所变化;那么,这个技能的消耗、cd和伤害值要怎么做呢?
假设一个技能,可能需要预判对手行为,玩家预判的准确度我们可能通过各种手段和经验得到一个预期值(不一定准,但是后续可能会统计玩家数据进行调整,典型的例子是Dota里月之女祭司的箭和屠夫的钩,前期版本调整过无数次,原因就是需要不断根据玩家平均水平设定,当然绝大多数指向性技能命中率就是100%,有些技能的命中率也是非常容易估准,所以我们看到骷髅王和流浪剑客的锤子都基本没怎么改过);通过这个预期值,我们可以构造一个状态转移矩阵,根据伤害可以计算出这个技能直接致死的概率;然后把眩晕作为,进而统计出我们想要的、关于这个技能的收益,或者根据收益逆推成本。
那为什么不一开始就用技能举例呢?一方面,讨论强化相关的文章比较多,参考起来比较方便,反正我的最终目的是引出状态转移矩阵基于这个状态转移矩阵的计算方法,至于这个方法能应用在哪些方面都是看自己的需求,用来买也是可以的;另一方面,讨论强化从x到y多简单啊,直接用Exy就能表示了,“从正常状态到眩晕和从正常状态到死亡状态……”这种说法,太绕口了吧=_=当然,最主要的原因还是,我就是爱这么胡扯啊^_^
所以最后还是写成了一篇包裹在“干货”外衣下的方法论,唉,人生不如意十之八九啊……
专栏地址:https://zhuanlan.zhihu.com/p/37430368,