查看原文
其他

策划丨游戏数值深入剖析:判断玩家命中的随机函数

2018-02-12 Gad-腾讯游戏开发者平台

作者:David Kennerly

译者:kingcrimson


一只剑刃蜘蛛正在逼近你。它击中你了,你却挥空了。它再次击中你,你又挥空了。如此反复,直到你没有一丝还手的力气。你阵亡了,而那只两吨重的节肢动物则得意的趴在你的尸体上。难以置信?不。很难发生?是的。但是如果有足够的玩家和足够的时间,这种情况还是肯定会发生的。剑刃蜘蛛不是个狠角色,只是玩家的运气太差了。多么令人沮丧,这足以让一个玩家放弃这个游戏。



游戏机制”是每个游戏设计师都会讨论的术语。每个人都同意游戏机制是游戏设计的一个重要组成部分。但是很少有人深入讨论游戏机制的设计怎样使玩家感到满意。在这篇文章里,我会详细剖析与角色扮演游戏密切相关的一个游戏机制——判断玩家命中的随机函数。好吧,让我们带着一点数学思想来看看这个游戏机制是如何被诠释的。


减少挫败感


在开篇的情节里,一个减少挫败感的方法是减少随机。几个大型MMORPG,像《天堂2》,减少了命中和伤害的多样性。Alex Chacha阐述了其原因,如果一个连续失败判定的概率大于0,那么它在长时间游戏里一个角色生命周期中出现的几率是非常高的。("Randomness," MUD-Dev Mailing List, February 2004)一旦这种情况发生,必将给玩家带来挫败感。所以,在本文中,我们把这连续失败称作挫败感。


减少挫败感发生的一个手段就是改变游戏中随机模型的机制。例如,我们可以改变随机取样的方法,把重置随机改为非重置随机。


首先,我们要理解这个词语,这就需要一点点概率和统计学基础。这不会太难,因为概率理论自从公元1654年以来就被广泛应用到色子和牌类游戏中了。在概率学里,一个随机结果被提取出来的过程叫做取样。有两种取样的基本方法:重置(例如掷色子),非重置(例如抽取扑克牌)。二者的差异看起来很简单,但是其中的含义,是非常具有戏剧性的。


回到手头的问题来:为了减少挫败,把重置随机改为非重置随机。基本上就是把掷色子模式改成抽牌模式。让我们用开放式游戏内容(OGC)来当作示例背景。这个系统是基于威士智公司的《龙与地下城 3.5版》的。所以,我们要替换掉投掷20面色子,而从打乱的20张牌里抽取牌。


这个机制的关键不同之处可能体现在一个单独的牌组。在重置随机中,每次取完一张牌后,会把它放回到牌组中重新洗牌。而非重置随机,则取完这张牌后直接丢弃,继续取剩下的牌。当牌组中的牌全被抽完时,丢弃的牌组成的排堆再重新洗牌组成新的牌组。来分析如何减少挫败感,我们可以把一张表示击中的牌从牌组中取出,打乱剩下的19张牌。然后把这张击中牌放到牌组的最上方。


假设,在OGC规则中,一个玩家拥有+0的近身攻击加成,他面对防御等级11的对手会有50%几率击中。这可以用重置随机来建模,按照50%的成功概率。而非重置随机的建模,可以想象成10张击中牌和10张落空牌。如果再需要些细节来统计,可以把20张牌分别赋值1~20。或者把10张牌赋值为"命中",另外10张牌赋值为"落空"。在非重置随机里,玩家会在10张落空牌队列中抽取一张,但是挫败感远远少于在重置随机中的抽取。那么这种差距到底有多大?


牌的计算


计算重置随机的挫败概率是很简单的。设f为连续落空的次数,作为挫败的结果,我们可以考虑10次落空。重置随机中,这相当于带有落空概率的二分法,来测量连续试验。我们可以理解方程1,单一失败概率是50%。逻辑比较简单。一个队列中10次失败的总概率就是10次失败概率的乘积。所以,在10次攻击序列中,挫败概率约等于千分之一。


方程1.重置随机的挫败概率


计算非重置随机的挫败概率就复杂了,因为每次攻击命中的概率受上一次命中或落空的影响。解决这个离散概率问题的通常做法是计算出每种可能发生情况的数量,再除以所有可能形成攻击序列的次数之和。


为了计算可能出现的挫败事件,概率相当于20次攻击中连续10次落空可能性的数量。我们只做简单的分析并且要进一步限制挫败,于是把第一次攻击算作命中里的一次。意味着在OGC中掷出一个自然数20。因为挫败(如10次连续落空)是不可变的,我们得出一个关于10个里面选出1个序列可能性数量的方程。利用排列组合的知识,化简出方程的零解,见方程2。


方程2.非重置随机中造成挫败的可能性的数量


然后计算19次攻击中形成9次命中10次落空序列可能性的总数。见方程3。


方程3.非重置随机中所有攻击可能性的数量


用挫败可能性除以攻击总数,我们得出了挫败的概率,见方程4。所以,在20次攻击中挫败的概率约等于万分之一。


方程4.非重置随机中挫败的概率


用等式1除以等式4,我们可以看到非重置取样大量的减少了挫败的几率,见等式5。为了简化分析,我们把重置随机的挫败概率乘以2(或非重置挫败概率除以2),因为非重置的概率是20次攻击序列中的,而重置的概率是10次攻击序列中的。


方程5.非重置大量减少了挫败


很明显,这种机制减少了挫败。此外,这种非重置机制保证了10次以上的连续落空是绝不会发生的(因为10次以后总会命中)。


尽管以上分析只是一种方法,用来处理玩家攻击对手的一种情况(如近身攻击+0对防御等级11),但是我们同样可以分析出对应所有情况的方法。同样的,这种分析也可以用于任何产生挫败的情况。假如产生挫败的最大限度容差是5次连续落空,那么牌组可以被分成两个单独的牌组,都是非重置的,以至于每个单独牌组的连续落空都不会超过5。为保持一致性,两个牌组要被平均分布(例如75%成功率=7/10+8/10)。


上帝不掷色子


采用牌组机制的耗费不是很高。绕开数学,从计算机科学角度会很好的阐明这点。每种机制都是由一个算法(精确的规则)来执行的。计算色子机制所耗费时间的复杂程度是很直观的,见表1。


表1.色子机制的算法概要


牌组机制也不会太复杂。一种原始的洗牌算法可以让线性时间内每次抽取都是随机的。所以,这意味着一次花费的时间不会比19次重置的色子机制花费的时间要多。这样的洗牌在20次攻击里只需要调用一次。在表2中,牌组机制的时间复杂度(执行算法总时间耗费)比色子机制的要有优势,但不是很大。尽管比色子机制要多一个步骤,但从洗牌后的牌组中抽取一张牌(c)是微不足道的操作。此外,借助高效的洗牌算法,洗19张牌(s)并抽取1张与掷一个19面色子(d)没有什么区别。


表2.牌组机制的算法概要


一种更出色的算法会在每次攻击里只洗一张牌,表示每次攻击中只随机一次,如表3所示。这种算法不会改变整体的时间复杂度,但是会使计算结果更加平均,这样每20次攻击后就不会有延迟(洗牌的时间)。


表3.应用逐步洗牌法的牌组机制算法


当然,与色子相比,牌组需要空间去存储,但是对于玩家来说,就好比50字节只再多了19位而已。


阿尔伯特·爱因斯坦曾经陈述过另一个详细的机制,一个关于宇宙中元素构造的机制。当他阐述量子物理中随机模型时,他说:"上帝不掷色子。"而在RPG中,造物主则用纸牌来代替色子。


这要紧吗?


用色子还是牌组要紧吗?二者的概率都是可以忽略的,看起来好像不会引起挫败。但是,单单这很小的概率,像千分之一,就足以让玩家有的受了。


要理解这点,我们首先需要学习另一个离散概率的分布。我们要知道玩家会有多少种挫败情况出现。每种情况非常稀有,所以这应该是泊松分布,E(X)。这能得出一个理想的近似值,如方程6所示。


方程6.计算挫败的泊松分布模型


一般而言,泊松分布用来测量单位时间内发生事件的数量(λ)。我们已经计算出单一情况下挫败的概率(p)。需要确定的是产生挫败的攻击序列的总数(n)。让我们考虑两个拥有足够多攻击序列的场合,大型多人游戏和单机游戏。


案例研究:MMORPG


对于MMORPG中一个简单的例子,平均每个玩家一小时平均有1000次攻击。粗略的估计一下,会有100个10次攻击序列(实际上只有十分之一的连续失败序列是符合这个划分的)。在这里我们简化一下,设定一个小规模的MMORPG,平均每天会有100名攻击是均匀分布的玩家,并且彼此的攻击是独立的。那么会得出100 序列/小时(24小时一天,一月30天)。这样算来一个月会有72000个攻击序列。因为基数非常大,概率又非常小,所以符合泊松分布,λ = n p。在方程7种解出挫败的期望值。


方程7.重置随机的每月挫败期望值


所以,经过简单的估算,在一个不复杂的游戏中,采用类似掷一个1d20色子的机制会造成每月有70次挫败序列(比如连续10次攻击落空)。然而,非重置随机(20张的牌组机制)的挫败期望值在方程8中被计算出来。因为是20个的序列,取近似值,结果要除以2。


方程8.非重置随机的每月挫败期望值


可以看出,挫败的发生会少18倍。挫败的分布情况以泊松分布形式在图1中体现。因为只会出现整数,在连续的泊松分布中取中点的近似值。


图1.非重置(蓝)与重置(红)挫败的泊松分布


根据分布图的对比,很明显能看出非重置毫无疑问的减少了挫败的发生。


案例研究:单机RPG


没有理论或实践的依据来证明这种方法不能应用到单人和多人RPG的战斗中去。事实上,一个游戏卖出了百万份拷贝,已经相当于多人在线游戏的期望数字。这只是畅销度与时间的区别。泊松分布同样可以应用到单机游戏。假设一个单机RPG的玩家平均花费10小时在游戏上(毕竟有很多玩家玩不久就放弃了)。如果攻击比率保持不变(每小时1000次),那么只需要卖出7200份游戏拷贝就能达到上述MMORPG一个月的效果。


每种机制要设计的简约而不简单


爱因斯坦也说过:“凡事要尽量简约,但不要太简单。”不要让数学精度计算支配了你的分析。在掌握了一个机制的奥妙,确认它对游戏影响的条件下,适当的数学计算是必要的。


在这个例子里,我们对比了两种机制的差别,不是依照所有使玩家挫败的情况,而只是针对一种机制的分析。我们简化了一些情况只是为了让计算更简单明了。我们不是想把玩家的命中几率控制在50%以上或以下,也不是为了坚持色子机制泊松分布的独立性。聪明的读者应该发现牌组机制始终没有使第一张牌随机化。这样做是为了避免复杂的概率计算。所以,我们的结果只是针对一套特殊牌组的近似值。


更多的精确分析对证明牌组机制的适用性没什么帮助。死记硬背只能让设计师合理的解决问题,但不能正确的解决问题。在本文中,我们仔细推敲了一种游戏机制,忽略了其他关乎玩家感受的元素。尽管数学方法很好掌握,但是通过分析玩家挫败类型来计算玩家损失的分布仍是一个需要毅力的过程。


关于作者


David Kennerly在美国与韩国指导制作了5款大型多人在线游戏。他参与韩国第一款全球化游戏The Kingdom of the Winds的本地化工作,并设计了Dark Ages: Online Roleplaying(黑暗之光)的社交系统。在1997年加盟Nexon之前,他为20世纪福克斯公司设计了X-Files Trivia Game,并负责US Army韩国网络的故障维护。


David鼓励有创造力的开发者和玩家。他帮助组织了MUD-Dev研讨会,并且创立了一个在线图书馆。David为Charles River Media,ITT Tech,Westwood College,Gamasutra.com,IGDA 撰写设计文章。要与作者进行交流,请访问他的网站:http://www.finegamedesign.com/


译者注:


重置和非重置的说法我感觉听上去更好理解些,一般概率教材中翻译为“放回取样”和“不放回取样”。文中的一些方程都是基本的概率学公式,很好理解。作者的观点是非常有用的,因为CRPG中,尤其是MMORPG,平衡性尤为重要。除了玩家之间的平衡,重要的是玩家与系统间的平衡。采用了D20规则虽然简单,但是在游戏中有很大几率出现文中提及的现象,例如平时跑团就经常能遇到连续手气好或手气坏的情况。这在CRPG中会给玩家带来挫败感。采用牌组随机可以避免这种情况,但也要因地制宜,合理有效的去运用。


以下给出两种随机抽取的一个简单算法示例(fake code):


  struct Sampling

  {

  int value;

  Sampling *prev;

  Sampling *next;

  }

  function SamplingWithReplacement

  {

  int r=Random();

  for(i=1;i<=n;i++)

  {

  if(i=r)

  {

  choose(Sampling);

  }

  Sampling=Samping->next;

  }

  }

  function SamplingWithoutReplacement

  {

  int r=Random();

  for(i=1;i<=n;i++)

  {

  if(i=r)

  {

  choose(Sampling);

  n--;

  Sampling->prev->next=Smpling->next;

  }

  Sampling=Samping->next;

  }

  }


今日推荐

给玩家定一个小目标?

多人游戏关卡设计视觉化指南

十分钟,看懂研发、发行和渠道的那些事儿

一键添加

加小编微信,享双重福利

1.加入GAD策划交流群,获取行业干货;

2.领取17G腾讯内部分享等独家策划资料。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存