参考:http://developer.178.com/201101/90441004081.html
一只剑刃蜘蛛正在逼近你。它击中你了,你却挥空了。它再次击中你,你又挥空了。如此反复,直到你没有一丝还手的力气。你阵亡了,而那只两吨重的节肢动物则得意的趴在你的尸体上。难以置信?不。很难发生?是的。但是如果有足够的玩家和足够的时间,这种情况还是肯定会发生的。剑刃蜘蛛不是个狠角色,只是玩家的运气太差了。多么令人沮丧,这足以让一个玩家放弃这个游戏。
"游戏机制"是每个游戏设计师都会讨论的术语。每个人都同意游戏机制是游戏设计的一个重要组成部分。但是很少有人深入讨论游戏机制的设计怎样使玩家感到满意。在这篇文章里,我会详细剖析与角色扮演游戏密切相关的一个游戏机制--判断玩家命中的随机函数。好吧,让我们带着一点数学思想来看看这个游戏机制是如何被诠释的。
减少挫败感
在开篇的情节里,一个减少挫败感的方法是减少随机。几个大型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/
参考文献
Jay L. Devore, Probability and Statistics for Engineering and the Sciences. "Chapter 3: Discrete Random Variables and Probability Distributions." 6 ed. Brooks/Cole: USA, 2004.
来自:GameDev.net
http://www.gamedev.net/reference/articles/article2206.asp
译者注:
重置和非重置的说法我感觉听上去更好理解些,一般概率教材中翻译为“放回取样”和“不放回取样”。文中的一些方程都是基本的概率学公式,很好理解。作者的观点是非常有用的,因为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;
}
}
分享到:
相关推荐
这个过程要考虑游戏的平衡性,避免过多的2同时出现导致玩家无法进行有效的合并。 4. **用户界面**:游戏界面通常使用HTML和CSS构建,JavaScript负责动态更新界面。每当玩家进行一次移动,都要更新界面显示的数字,...
【数据集或时间序列的随机性检验】 检验数据集或时间序列是否随机分布,可以通过绘制Lag Plot(相关图)。如果图上的点呈现散乱分布,那么可以认为数据是随机的。 【创建混合类型数据的DataFrame】 在Python中,...
Python是一种广泛应用于Web开发、数据分析、人工智能等多个领域的高级编程语言,因其...在实际操作中,你可能还需要处理额外的细节,如用户输入、游戏得分显示、游戏暂停和重置等功能,这将使你的代码更加完整和实用。
**课题背景**\n 贪吃蛇游戏自1976年首次出现在计算机上以来,因其简单易懂的游戏机制和高度的可玩性而广受欢迎。随着移动设备的普及,尤其是J2ME作为早期移动设备上的主要开发平台,将其移植到手机成为了必然趋势。...
开发者需要确保代码无误,游戏运行流畅,同时可能还需要考虑游戏的可玩性和平衡性。 9. **用户界面**: 虽然乒乓小游戏相对简单,但仍然需要一个友好的用户界面,包括游戏开始、暂停、重置、得分显示等功能。这...
- **隐藏层:** 负责对输入数据进行多次非线性变换。 - **输出层:** 最终输出结果。 **激活函数的作用与类型:** - **作用:** 引入非线性变换,使模型能够拟合更复杂的函数。 - **类型:** - **Sigmoid:** 适用...
6. 内存刷新:对于DRAM,系统必须定期执行刷新操作以重置电容,保持数据完整性。刷新过程通常是自动化进行的,由内存控制器管理。 7. ECC内存:为了提高数据的可靠性,一些系统使用具有错误校验码(ECC)的内存,它...
2. **数据需再生**:由于内部电容的漏电现象,DRAM中的数据不能永久保持,需要定期通过刷新操作来重置电容,以维持数据的完整性。 3. **定期刷新**:由于漏电阻的存在,DRAM单元中的电荷会逐渐泄漏,因此需要每几百...
1. **Randomize samples**:随机采样选项允许渲染器在计算发光贴图时随机选取采样点,而非按照网格顺序,这样可以减少重复和模式感,提高光照的自然度,但可能会略微增加渲染时间。 2. **Check sample visibility**...
在电子政务领域,确保数据的安全性和隐私保护是至关重要的。标题“电子政务-将存储器恢复为出厂状态的电子装置及方法”暗示了这个压缩包包含的信息可能涉及到如何在电子设备上安全、有效地清除存储器中的数据,使其...
1. **Flash/ROM**:用于存储程序代码和常量数据,具有非易失性特性,即使断电后也能保留数据。 2. **RAM**:随机存取内存,用于存储运行时数据和变量,具有高速读写能力,但断电后数据会丢失。 3. **外围模块**:...
动态验证码是一种重要的网络安全技术,主要用于防止自动化程序(如机器人或恶意脚本)对网站或...在设计和实现时,开发者需要平衡用户体验和安全性的需求,选择合适的验证码类型,并确保其与后台验证系统的无缝集成。
当OFDM符号中的部分子载波由于数据随机性而同时达到峰值时,整个信号的功率会显著增大,导致较高的PAPR。因此,降低PAPR是OFDM系统设计中的重要课题。 以下是一些常见的PAPR降低技术: 1. **剪枝法(Clipping and ...
同时,算法引入了粒子进化的概念,通过重置陷入局部最小的粒子的位置,使得它们有机会跳出局部最优,避免了早熟收敛,从而提高了算法的稳定性和全局搜索性能。 算法的具体步骤如下: 1. 初始化:随机生成多个粒子的...
Python作为一种高级编程语言,因其语法简洁、易读性强的特点,被广泛应用于数据科学和机器学习领域,特别是强化学习(Reinforcement Learning, RL)。强化学习是人工智能的一个分支,它通过与环境的交互,让智能体...