查看原文
其他

《80 days》:如何以软件工程的思路编写一部互动小说

厌氧菌 厌氧菌的故事工程学实验室 2021-04-03

互动小说(Interactive Fiction)是一种非线性的文字媒体。与传统的小说相比,每一次阅读一部互动小说时,读者能够在一定程度上影响呈现在他面前的那个特定的线性故事;因此每一次阅读时,根据读者的输入不同,会产生不同的线性故事。《惊险岔路口》(Choose-your-own-adventure)系列小说是这种媒体脱离计算机的一个典型例子。小说在讲述故事的中途,会时不时要求读者作出选择,并根据读者的选择指示读者翻到相应的页数继续阅读,以这种方式根据读者的选择动态地产生一条故事线。


《惊险岔路口》(Choose-your-own-adventure)系列小说



通过借助计算机软件环境的模拟,互动小说能够容纳更多更复杂的文字选择支,同时能够以图像、视频和音频等多媒体素材辅助加强文字描述。这种数字化了的互动小说,通常被认为是电子游戏的一种,并在电子游戏的上下文中被称作是文字冒险游戏(Text Adventure Game)。这类游戏的典型例子有早期的Zork系列,最近的生命线(Lifeline)系列,以及不计其数的来自某岛国的AVG游戏。


来自日本Spike Chunsoft的文字冒险游戏《街:命运的交差点》,其续作就是被Fami通评为满分的《428 〜被封锁的涩谷〜》


虽然文字冒险游戏能够在特定人群中受到欢迎,它却一直不是电子游戏具有代表性的一个类别。使用计算机软件环境来模拟一本实体书面前读者手动的翻页操作,似乎并不足以改变这种媒体的本质——它仍然只是作者提前写好的一个有复数个版本的故事,读者作出非常有限的选择,并很容易就能通过多次通关穷尽作者提前设计好的有限的可能性。

 

当我们想象一个典型的“电子游戏”,往往我们脑海中浮现出来的是诸如物理引擎、实时战斗这样的关键词;而一部互动电子小说,尽管它有互动性,无论怎么想都还是更像一部小说。这样的刻板印象持续已久。之所以会有这样的观点,至少对我来说是因为人们潜意识中要求一个游戏应当首先是一个有机的“系统”。并不是所有相互作用的元素的集合都值得被看作一个系统——它应当具有一定程度的复杂性(Complexity)。如果这个集合中的元素相互作用的结果只有非常有限的可能性,通过简单的列举就能穷尽,那么显然这个集合不值得被看作一个系统。


一个典型的基于物理引擎的3D游戏


一个基于物理引擎的实时战斗游戏,其游玩路线的个数尽管理论上说不是无穷多的(毕竟物理引擎是数字化的),但要通过反复游玩穷尽所有可能的游玩过程,对于人类玩家来说是几乎不可能的任务。与之相比,文字冒险游戏的游玩路线就极其有限。在一个基于物理引擎的游戏中,玩家甚至有可能发现连设计者自己都没有想到的新玩法,这一点对于文字冒险游戏就更是难以想象。文字冒险游戏的设计似乎就要求至少作者本人要穷尽所有选择支。从这一点来看,似乎文字冒险游戏从根本上就不可能达到一个“典型”的游戏应该具有的机制复杂性。文字冒险游戏跟基于物理引擎的游戏之间在机制复杂度上的差别,简直相当于有限集合(Finite Set)和无限不可数集合(Inifinite Uncountable Set)之间的差别。

 

而这样一个听起来似乎很有道理的观点,至少在我心里,被来自英国Inkle工作室的文字冒险游戏《80 days》动摇了。

 

《80 days》是Inkle工作室于2014年推出的一款基于儒勒·凡尔纳同名小说改编的文字冒险游戏,曾获2016年IGF最佳叙事奖。玩家在其中扮演福克(Fogg)绅士的仆人路路通(Passepartout)。跟小说不同,在游戏中路路通(玩家)是安排旅行一切事宜的人,包括探索路线、规划路线、通过商品交易赚取旅费。作为福克绅士的仆人,路路通还要照顾好福克绅士,维护福克绅士的健康值,甚至经营好跟福克绅士的关系。

 

跟小说中的情节一样,福克绅士因为跟人打了个赌,要跟路路通从伦敦出发一直向东行进环绕地球一圈,在80天内从地球另一边回到伦敦。城市间存在的通路一开始是完全未知的,需要通过购买交通时刻表、在城市中进行探索、在旅途中与人交谈等方式获得。路线的选择很有策略性:有的路线长、有的路线耗费大量资金、有的路线需要抛弃货物、有的路线消耗福克绅士的健康值多,因此每次离开一个城市时对下一段路线的选择都需要一番权衡。旅费的赚取需要在城市间进行商品交易,而商品交易又因为有限的货物空间和后续旅行路线的不确定性而颇具挑战性。


游戏基本界面


通过上面的描述,我们大概可以想象一个抽象的旅行规划模拟器——玩家面前是一个图(Graph),节点是地球上的城市,有向边是城市之间的通路;每条有向边要通过玩家的特定操作激活;每条有向边有费用、长度、健康值消耗等数值属性。玩家要做的不过是在这个图上找到一条从叫做伦敦的节点出发最后又回到这个节点的一条路径,这个路径上所有边的长度加起来不能超过80天,并且每条边的费用都必须小于等于当玩家处于这条边的起始节点时持有的资金。这听起来一点也不好玩,反而更像是一道枯燥的数学题。

 

真正赋予这个游戏其核心体验的,是这个旅行规划模拟器的内部数值运作最终呈现给玩家的形式——文字。游戏有地图界面方便玩家直观地考察和选择路线,有城市界面显示玩家在每个城市中都可以执行的那几个固定的操作(市场,银行,旅馆,探索),有一个行李箱界面允许玩家安排物品在行李箱中的空间位置(并没有实际的策略性)。这几个界面最多属于UI,而游戏实质内容的展开,即旅行的过程,完全是以文字描述的方式呈现给玩家的。


游戏的绝大部分内容都只是以文字描述的方式传达给玩家


游戏的文字描述非常有魅力。它将整个地球的19世纪搬到了蒸汽朋克的设定之下。那些我们所熟知的19世纪的历史事件与幻想中的蒸汽朋克元素相互作用,产生出了许多有趣的化学反应。游戏中的交通工具丰富而充满想象力,除了飞空艇这种司空见惯的蒸汽朋克交通工具,还有机械巨鸟、水下火车,蒸汽自行车、能够在船舰和潜艇间自由切换的水路交通工具等等。游戏中泰姬玛哈陵的所在地阿格拉甚至是一座巨大的机械移动城市。这个蒸汽朋克世界也是一个比真实的十九世纪更加开放和政治包容的世界:我们可能遇到穿着满族旗袍的女飞空艇船长和个性强势的中东女发明家,甚至能在新奥尔良某酒吧与一个白人和黑奴混血的男性同志调情,等等。游戏中的文本量有500,000个单词,收录了150+个城市,数百条城市间的旅程都有它们各自的故事,并有近一万个选择支。几乎没有两个玩家经历完全相同的故事线,通过反复通关穷尽所有故事线是几乎不可能的事。跟大多数的文字冒险游戏不同,《80 days》甚至没有一条所有玩家都必须经历的主线。


阿格拉是一座巨大的机械移动城市


尽管《80 days》在游戏机制上的目标是在80天之内回到伦敦,但其优秀文字叙事创造出的在蒸汽朋克的19世纪到处旅行的体验实在过于享受,以至于很多时候玩家会直接选择忽略80天这个时间限制——毕竟如果只有80天的话,能够访问的城市数量实在是很有限。将游戏的目标从“80天内回到伦敦”强行改为“访问尽可能多的城市”,反而由于鼓励玩家更加深入游戏的叙事和贸易系统而看起来更像是这个游戏的真正玩法。

 

《80 days》的编剧Meg Jayanth在GDC15的一个报告上曾说过:

 

My job as a writer was to tempt the player into making bad decisions, to teach them that a bad strategy could lead to a great story, and may even a better game experience overall.

我作为编剧的任务是引诱玩家作出坏的选择,从而教导他们一个坏的策略可能引向一个很棒的故事,甚至在总体上反而带来了更好的游戏体验。

 

由此看来,忽略80天的时间限制而到处绕远路,可能本来就是官方承认的玩法。

 

按照我们前面的理论,一个很难穷尽全部故事线的互动小说,似乎从根本上就是不太可能实现的。那么《80 days》究竟是如何实现这样丰富的故事可能性的呢。我认为其关键在于两点:


故事模块的解耦

 

一个非线性的叙事结构由一个一个可能相互连接的故事片段组成,我们将这些故事片段称为故事模块,并简化地认为故事模块的数量是决定作者写作工作量的决定性因素。

 

典型的传统文字冒险游戏的故事结构是树状的。故事从一条主线开始,然后分支成各条支线,各条支线再各自进行分支,并各自结束。可以从图中看出,这种结构的互动叙事,其故事线的个数不会超过树结构的叶子节点的个数。当然,具体的传统文字冒险游戏的叙事结构可能不是严格树状的(例如存在分支的汇合等),但大体上还是接近这种结构。

 

而《80 days》的故事结构大体上是一个图结构——如果我们忽略不规则出现的旅途随机事件的话,每一个环球旅行路线都等价于一条故事线,由每个城市和旅途中发生的故事片段作为其节点。根据图论,一个图中存在的路径的个数最高是可以达到这个图的节点的指数级的(注意是路径的个数而不是边的个数)。通过将树结构的叙事变为图结构的叙事,在故事模块数量相同的情况下,故事线的数量能够获得指数级别的提升。


传统文字冒险游戏《极限脱出:善人死亡》中的树状叙事结构


《80 days》中的图状叙事结构


但是,这种叙事结构的转变不是一件简单的事。一般情况下,一个故事模块不是一个与其他故事模块完全独立的故事片段:有的故事模块需要发生在它之前,有的要在它之后才有可能发生。树状的叙事结构是一种对于作者来说特别容易理解和掌控的一种结构,因为它是层次化的。故事模块在一个树状结构中有一个全局性的清晰的前因后果关系——一个位于第n层的故事模块,其前因事件不可能位于第n层以后。这个全局性的层次就像是一个时钟,它预先就规定好了玩家在经历任何一条故事线时都必须遵循的时间线。

 

而图结构就不存在这种全局性的层次;玩家在游玩时的时间线,在作者设计叙事时是不确定的。这种情况下,没有一个全局性的时钟让作者能够直截了当地将每一个故事模块放进它所属的那个时间段里。其结果就是,作者很难思路清晰地构造这个叙事图,因为除非他穷尽所有可能的故事线,总有可能存在一条故事线是不合理的。而因为故事线的个数可以达到故事模块的指数级别,穷尽所有可能的故事线是一件非常困难的任务。更可怕的是,每当作者增加、删除、修改故事模块,为了系统性地分析对其他的故事模块的影响,作者又需要穷尽所有可能的故事线。这使得以这种方式设计具有一定规模的图结构的叙事几乎是不可能的事。

 

那么,如何设计一个图结构的叙事呢?其要点在于解耦故事模块间的前因后果关系,并清晰定义每个故事模块的接口。在传统树结构叙事的设计中,作者可能会直接定义,A事件会导致C事件,B事件也会导致C事件。而解耦故事模块间的前因后果关系,要求作者明确定义使得A事件和B事件都导致C事件的叙事要素。

 

例如,假设A事件是“玩家到达班加罗尔”,B事件是“玩家到达马德拉斯”,而C事件是“玩家看到街上的雇佣兵暴动”。那么我们就需要定义导致C事件的原因是“玩家到达印度”——这不再是一个具体的事件,而是一个概念类似于软件工程中的“接口(Interface)”的抽象事件。我们接着定义A事件和B事件都是“玩家到达印度”这个抽象事件的实例。这样,我们就实现了事件A、B与它们的后果事件C之间的解耦。

 

作者只需要像这样定义每个故事模块的接口,而具体的故事模块间的连接方式就能够算法性地从接口的定义中推断出来。尽管每次增删改故事模块对具体故事模块间连接方式的影响可能是全局性的,它对故事模块接口定义的影响却是局部性的。这种设计方式为作者带来了“通过掌控局部而掌控整体”的可能,从而使得设计大规模的图结构叙事成为可行的方案。


定义抽象的故事模板,根据玩家的选择、游戏进行的状况和随机变量实例化

 

难以穷尽故事线并不意味着难以穷尽故事的内容。如果故事模块的数量是确定的,那么玩家就算没有穷尽故事线,只要穷尽了所有故事模块,不就相当于穷尽了故事的内容了吗。因此单纯解耦故事模块,还不足以实现真正的故事复杂性。但如果玩家永远也不能真正阅读到每个故事模块“本身”,而总是它的某个视情况而变的特殊版本的话,事情就没那么简单了。

 

游戏以两种方式实现这一点:首先,每一个故事模块都是一个独立的交互式非线性文本片段。这些文本片段大多采用“分支-汇合”的结构——故事中会在人物对话和行动、主角看待事件的视角和态度、甚至单纯的文字描述风格上产生文本选择支。但因为故事片段最后的结局通常只有1~3个,多数分支最终会汇合到同一条主线。大多数文字选择支对这个故事片段局部的影响仅仅是装饰性的,但会影响到游戏系统对一些全局参数的取值——例如主角路路通的性格和与福克绅士的关系。从整体来看,每个故事模块都是一部交互式小说这一点极大增强了游戏的叙事复杂性。但由于每个故事模块都是独立的,可以局部性地进行设计,这一点并没有增加多少设计上的复杂性。

 

第二,游戏中有大量随机事件,例如路路通在城市中探索时会有人提供关于路线或者城市交易品的情报。这些随机性事件的主要目的是功能性的——例如提供情报,但这些随机事件同时又是一些具有叙事价值的故事小片段。例如在上述随机事件中,玩家可以选择跟情报的提供者继续聊下去,询问对方是如何知道这个情报的,然后得知一些发生在对方身上的琐事,等等。这部分叙事虽然没有功能性的作用,但它让这些随机事件融入了作为一部互动小说的整体,而不仅仅是一个系统弹窗通知玩家某个游戏变量值发生了变化,从而丰富了游戏整体的叙事体验。


导致玩家获得新情报的随机事件


玩家在多次经历某一类型的这种随机事件之后,会发现它们有一个共通的形式。例如,上面提到的情报提供事件总是以“我花了几个小时散步,遇到一个人(伴随对这个人的相对细致的描述);他告诉了我一个情报(伴随对这个情报的内容描述)”的形式开始,玩家接下去总是可以选择支付给对方1镑作为感谢,询问对方是如何获得这个情报的,或者告诉对方这个情报对自己可能并没什么用。但具体是一个什么人来告诉玩家这个情报,这个情报的内容是什么,对方是怎么知道这个情报的、在支付给对方1磅或者告诉对方这个情报对自己没用之后对方的反应,却是每一次都可能不一样的。

 

参照软件工程中的类似的概念,我将这种类型的叙事模块设计称为“抽象故事模板”。它定义了一个故事片段的骨架和关键性的叙事要素,以确保这个故事片段不管怎么变化总是能够完成它的叙事目的。但它同时还定义了这个故事片段的可变要素及其可变化的范围,使得这个故事片段在完成其叙事目的的前提下,能够根据叙事“运行时”的情况生成那些在设计阶段没有确定下来的可变要素。以这种方式,玩家能够拥有更加丰富的阅读体验,而对于设计者来说,这部分故事内容的不确定性又并没有实质性地增加设计的复杂度。




由以上两点我们看到,尽管文字冒险游戏背后没有物理引擎,它仍然能够通过组合爆炸的方式达到可观的复杂性。当一个文字冒险游戏达到了这样的复杂性,以至于通过反复通关穷尽其内容成为几乎不可能的任务时,我们还有什么理由不称它为一个有深度的游戏呢?


游戏中在北美洲可能触发的拳击比赛事件,其中的选择支细致到每一个回合是出重拳、轻拳还是防御,可以看作是一个回合制战斗系统的文字表示


前面我们提到,传统的文字冒险游戏更像是小说而不是游戏,这是因为文字冒险游戏中的文本绝大多数都是由作者预先写好的——在这些文本的背后并没有一个真正的“系统”。如果一个三维图形界面的游戏所有的三维动画全部都是提前渲染好的,只是根据玩家的指令播放相应的三维动画,我们同样也会认为这个游戏缺乏一个真正的游戏机制。但是,就像结合了玩家的输入在运行时即时渲染出的三维视频游戏背后有一个物理引擎,如果一个文字冒险游戏中玩家在屏幕上看到的文字都是背后的某个“文字引擎”结合了玩家的输入在运行时渲染出来的,我们还能说它不是一个真正的游戏吗?

 

一个物理引擎能够产生机制复杂度非常高的游戏,但这种机制复杂度并没有导致这种游戏的设计成为不可能的任务,这是因为物理引擎的设计有工程学的方法作为指导。既然如此,为什么我们不能同样在工程学方法的指导下,设计出机制复杂度非常高的文字冒险游戏呢?

 

《80 days》严格意义上是不是真的拥有这样一个文字引擎,可能还是一个有争议的话题。但是,它至少是这条道路上一个非常有意义的阶段性的成功。它让我们看到了文字冒险游戏超越人们对它的当下认知并达到一个全新高度的可能性。当真正意义上的文字引擎出现的时候,谁知道会出现什么样的文字冒险游戏。

 

最后,让我用Meg Jayanth在GDC15上说过的这句话作为结尾:


"We did this by thinking of the game world as a narrative version of a physical engine. 80 days as a game is a machine for telling story."

“我们将这个游戏世界设想为一个物理引擎的叙事版本。《80 days》作为一个游戏,是一个讲故事的机器。”


厌氧菌的故事工程学实验室




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

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