游戏设计与事件建模
现在来点完全不同的:我将采用事件建模——一种现代的系统设计方法——并尝试将其与上世纪 80 年代盛行的游戏类型相结合。具体来说,我将运用事件建模技术来设计一款互动小说 (IF) 游戏,讲述一只狗在主人不在家时恐吓自己家的故事。
什么是事件建模?
事件建模是由Adam Dymitruk推广的一种较新的技术。其目标是提供一个极其简单的系统设计视图,该视图遵循 Cucumber 和其他行为驱动开发(BDD) 工具所使用的 Given / When / Then 样式语法。
这种简洁性使其易于理解、学习和使用。它与 Given / When / Then 语法兼容,因此测试和识别需求变得非常简单。
事件建模的核心围绕着三种类型的实体:事件、命令和视图。我将在这里简要解释一下,但本文稍后会通过游戏设计中的具体示例来解释。
事件是指在系统上下文中发生的事情。在线购物系统中,事件可能是“用户登录”或“商品添加到购物车”。
命令是用户操作。用户告诉系统他们希望系统采取某种操作并期望得到响应。在购物系统中,命令可能是点击按钮将商品添加到用户的购物车中。
视图是系统向用户呈现系统当前状态信息的方式。在购物系统中,这可能是“确认购买?”屏幕,显示即将下单的详细信息。
稍后我们将在我们的示例中看到它是如何工作的。
什么是互动小说?
互动小说在 70 年代到 90 年代初作为一种回合制冒险游戏而流行起来。游戏中,玩家会获得一个区域和场景的文字描述,并输入他们想要做的事情。系统会解读他们的输入并做出相应的反应。
以下是一段虚构游戏的文字记录示例:
Game: You are in a small dimly lit room filled with empty pizza boxes and soft drink cans. A laptop sits open on a desk in front of you, displaying some code and an error message.
Player: Sit at desk
Game: You are now sitting at the desk in front of the laptop
Player: Read the error message
Game: The message says "Unable to allocate value to non-zero index"
Player: Debug error
Game: I don't know what a debug is.
Player: Fix error
Game: You don't see an error here.
毋庸置疑,80 年代早期的文本解析器让很多玩家感到沮丧,但这些游戏的前景很有趣,其中一些游戏有极具吸引力和身临其境的故事,弥补了图形的不足。
隆重推出“狗狗任务”
在本文中,我们将设计一款名为“Doggo Quest”的小型文本游戏的流程。游戏背景设定在郊区的一栋房屋中,玩家控制一只关在笼子里的小狗。你从笼子里出来后,混乱随之而来,玩家不断制造灾难,直到固定时间结束,主人回家。
这是一个简单的概念,有趣,并且很容易解释和随时加入,这使得它非常适合用作技术讲座的背景(为什么我选择这个主题作为开始)。
就背景而言,游戏世界是这样的:
这是在Trizbort中生成的标准交互式小说地图,描绘了一系列房间(方块),每个房间都突出显示了一些值得注意的物品。
您还可以将此地图视为一个状态机,其中玩家的当前房间作为一个状态:
一些设计考虑:
- 你可以用鼻子推箱子或者用爪子抓箱子,这样就能从箱子里出来
- 为了能够尝试打开门,玩家必须先看一眼它
- 如果玩家在 5 个回合内没有看过门,游戏会提示他们门看起来不同或不寻常
- 打开板条箱门后 30 回合游戏结束
- 每个房间都有一些有趣的东西可以互动
- 有些房间有窗户。你从窗户看到的景象取决于你打开箱子后是第几回合
- 有一个评分系统,如果你把外面弄得乱七八糟或者对着外面的东西吠叫,你就会得到分数
系统将支持的值得注意的动词(包括同义词):
- 前往 / 步行至 / 跑至
- 吠叫
- 思考一下
- 闻/嗅
- 咀嚼/舔/吃
- 爪子 / 轻拍 / 猛击 / 击打 / 踢 / 拳打 / 推
- 抓取/拉动/拾起/获取
- 跳上
由于玩家是一只狗,这些动词与许多其他冒险游戏不同。
游戏设计与事件建模
现在我们已经粗略地描述了游戏及其世界,我将尝试应用事件建模来描述游戏逻辑。
为此,我们将遵循事件建模背后的人们推荐的多步骤方法。
免责声明:我的初次尝试并不顺利,我会在文章后面再次讨论。目前,请关注步骤和概念,少关注我具体想用这个故事做什么,因为它没有成功。如果您想直接查看最终成品,请直接跳到下面的“重做实验”部分。
1. 识别事件
在这一步,我们识别游戏世界中可能发生的所有事件。虽然我们可以(或许也应该)将其限制为诸如“玩家输入了系统理解的单词”之类的事件,但“垃圾桶被撞倒了”之类的事件会更有趣。
因此,考虑到我的游戏世界,以下是我设想会发生的重大行动:
- 走出箱子(标志着游戏计时部分的开始)
- 撞倒垃圾桶
- 杀死一只苍蝇
- 吃了一只苍蝇
- 撕毁的文件
- 吃了面包屑
- 打翻了一杯饮料
- 撕开窗帘
- 在地毯上撒尿
- 毁了一只鞋
- 滚进垃圾桶
- 对着松鼠吠叫
- 对着婴儿车狂吠
- 对着狗吠叫
- 车库门打开(当车主即将返回时)
- 主人归来(标志着游戏结束)
2. 绘制随时间变化的事件
接下来,我们将为我们确定的每个事件创建一张卡片,并将其排列成一条水平线,左边是最早的事件,右边是最新的事件。
如果您使用颜色来制作卡片,事件建模插图通常使用橙色,但您也可以在每张卡片上简单地写上“事件”或“E”来说明类型。
在狗狗的任务中,最早发生的事件是狗狗从笼子里出来,而最后发生的事件是主人回家。有些事件必须在它们之前的事件之后发生,但除此之外,事件本身相当独立,我可以根据虚构的剧情随意安排它们的顺序。
以下是我确定的事件顺序:
通常情况下,您只有一排卡片,但为了本文的目的,我将它们分成两排。
3.线框图
对于基于视觉的系统,你需要绘制与各个事件对应的用户界面。对于 Doggo Quest,我们实际上只有一个视图:
然后,我们可以将此线框放在图表顶部,并说明命令的来源以及事件对显示视图的影响。由于我识别的所有内容都来自在底部框中输入并更新顶部文本框,因此为了保持简洁,我不会选择在 UI 中到处用箭头来表示这些内容。
4. 识别命令
接下来,对于我们已经识别的每个事件,我们将查看是否可以识别可能导致该事件的命令。
由于我们讨论的是一款基于文本的游戏,所以这实际上非常简单——我们只需要简化玩家可能输入的内容。例如Push door
或Eat the fly
。
我们将在图表中用蓝色表示这些命令,并添加从每个命令到其引发的事件的箭头。在某些情况下,我们还会添加从事件到命令的箭头,以指示这些事件是先决条件。
这是包含命令和事件的游戏设计图的子部分。
请注意,与大多数互动小说游戏不同,这款游戏并非真正意义上的解谜游戏,而是一个供玩家体验游戏机制乐趣的地方。因此,命令之间没有太多依赖关系,但有一些事件相互关联。
5. 识别视图
在传统的系统建模实验中,我们会识别与每个状态相关的具体视图。由于这是互动小说,我们唯一有意义的视图就是屏幕上的文本。此外,我们可以假设每个动作都会输出某种文本,这使得建模在很大程度上变得多余。
不过,为了说明这个练习的要点,我将通过添加从事件指向这些视图的绿色矩形和箭头来将分数的增加建模为视图。
6. 引入界限
接下来我们需要应用康威定律,将相关事件分离到各自的“泳道”中。
在更大的系统中,我们会将相关的项目划分到各自的子系统,甚至是单独的应用程序/服务中。由于我们开发的是一个简单的游戏,所以我们会选择一个更自然的边界:游戏世界的各个区域。
事件建模主张仅将事件移动到泳道中,但是该系统中与事件相关的依赖关系使得这种方法有些不吸引人,如下图所示:
相反,我们会稍微偏离事件建模规范,将命令也包含在泳道中。这是合理的,因为命令是特定于位置的。
其结果更加清晰:
注:如果我尝试在引擎层面而不是游戏设计/故事层面来表示事件,这些结果会更清晰/更简单。这里的分区包括解析器、故事数据和用户界面等。这也符合分区的目的,因为这样可以更轻松地将一个代码模块交给不同的团队。
7.精心设计场景
接下来,我们回顾一下建模实验的结果,看看是否可以识别出模型未涵盖的任何情况,如果可以,则添加它们。
看了图表的结果以及我为了简洁而做出的改动,我对结果并不满意。我还能清楚地发现一些没有涵盖的情况:
- 重新开始游戏
- 输入游戏无法识别的内容
- 观察物体
因此,我没有选择添加遗漏的案例,而是选择重新进行实验,并将重点放在引擎上。
在与其他事件建模者交谈时,花一些时间来习惯应用事件建模是很常见的,因此,我决定重新进行练习就是这个学习过程的结果。
重新做实验
因此,重新进行实验,但将重点放在游戏引擎事件上,我的事件集如下所示(按时间顺序排列):
- 游戏开始
- 命令已输入
- 句子标记(分解成单个单词)
- 遇到未知单词(例如 FooBarBaz)
- 遇到不支持的动词(例如 Yodel)
- 未检测到物体(例如,当没有婴儿车时吃掉婴儿车)
- 句子已验证
- 命令执行
- 计时器开始(当玩家走出笼子时)
- 计时器已增加
- 游戏结束
这一次,我将在系统中代表更多的参与者,因此我包括用户界面线框以及主要子系统来解释和执行玩家的意图:
添加命令和视图
接下来,我将添加相关的命令和输出视图。请注意,命令不一定非得由用户发起,因此各个子系统都可以执行命令来触发事件。
这是我的包含命令、视图和事件的新模型:
请注意,我还在本次练习中确定了一个新的线框图。游戏结束的用户界面与普通用户界面不同,因为用户无法输入命令。
最终,很明显,用系统事件而不是故事事件来表示系统是正确的做法,而且已经是这样了。
虽然我可以遵循建议并划分泳道以遵循康威定律,但有几件事对我来说已经很清楚了:
- 我将是唯一一个负责该项目的人,因此我只需要 1 个泳道
- 如果我确实想扩大规模,我会沿着垂直线划分项目,一个人负责 UI,一个人负责故事内容,另一个人负责词法分析器/解析器,还有一个人负责故事引擎。
由于我预计将图表分成泳道只会使情况变得更加混乱而不是有帮助,因此我拒绝第二次执行此步骤。
最后,检查模型后发现,游戏结束时缺少一些命令。修改该部分后,我们发现:
评估实验
经过最后的清理后,完成的事件建模图如下所示:
让我们回顾一下并评估一下这个练习的效果。
确实,第一次建模时我搞错了要建模哪些事件,但最终的结果是一个清晰易读的游戏流程顺序事件模型。这个最终结果可以用来考虑我将要构建的应用程序的架构和结构。
事件建模作为测试蓝图
事件建模不仅可以帮助我们捕捉需求并有效地将其传达给新团队成员,还可以为我们提供测试内容的良好大纲。
让我们看一下事件模型内部的示例命令:
这里,Tokenize / Lex命令由Command Entered事件触发,并将触发Sentence Tokenized事件或Unknown Word Detected事件,从而产生“我不知道 X 是什么”的视图。
我们可以将其写成一对测试标准:
给定一个包含未知单词的命令
当我将命令输入到标记器/词法分析器中
时,我应该会收到“检测到未知单词”事件
以及“我不知道 X 是什么”的响应
和:
给定一个只包含已知单词的命令
当我将命令输入到标记器/词法分析器中时
,我应该得到一个句子标记化事件
退一步来说,我们可以查看整个事件模型,并且无需付出太多努力就可以为整个应用程序生成一个良好的核心测试起始列表!
事件建模和 Doggo Quest
所以,使用事件建模,我现在有了一个构建和测试应用程序的良好计划。这本身就是一个胜利。
然而,我原本打算对故事内部的事件进行建模,但最终不得不放弃,转而使用事件建模。这对我来说意味着事件建模更适合系统建模,而不是应用程序内部状态的建模。没关系,并非所有工具都能解决所有类型的问题。
然而,事实证明,在互动小说中存在一种相当标准的方式来表示故事流程:谜题依赖图。
由于本文的目的不是讨论该技术,因此我不再对其进行解释,但《Day of the Tentacle》的制作者提供了一本出色的入门书,如果您感兴趣的话,我鼓励您查看一下。
对于那些好奇的人来说,Doggo Quest 的谜题依赖关系图如下:
下一步是什么?
好了,完成了。现在我们已经完成了引擎和故事事件的建模。
这个月我将构建这个游戏引擎并编写故事,为今年计划就构建应用程序进行的几次演讲做准备。
这将是我最后一次探索游戏事件建模,但它达到了目的。
如果您想了解有关事件建模的更多信息以及它如何帮助您进行应用程序开发,我强烈建议您查看事件建模网站。它有一篇全面的文章和信息,可帮助您通过 Slack、Twitter 和各种事件了解更多信息。
感谢您的阅读,敬请期待!
使用事件建模进行游戏设计一文首先出现在Kill All Defects上。
鏂囩珷鏉ユ簮锛�https://dev.to/integerman/game-design-with-event-modeling-31fo