对于很多人来说,程序化生成是游戏的一大特点,每次进入游戏都不一样的内容,带来了很强的可重复性,也增加了游戏趣味。
然而,程序生成却并非那么容易做。如果过于随机,会导致游戏内容与主题的冲突,破坏了游戏的沉浸感;如果设计的很详细,又会导致随机性不是那么出色,还会带来很大的工作量。在这方面,独立游戏《Caves of Qud》可以说做的非常出色,这款在Steam好评率超过95%的古典RPG游戏为玩家们带来了大量的内容。
有不少玩家表示,“100小时才能玩完新手教学”,很多玩家用了3年时间都还没有通关全部内容。
据开发商 Games两名联合创始人Jason 与Brian 在GDC的演讲内容透露,游戏里大量的城镇都是用了程序生成。与绝大多数程序生成只是创造地形不同的是,他们还通过独特的工具设计了不同城镇的建筑风格、NPC甚至是文化。
以下是听译的完整内容:
Jason:假设你对程序生成有些了解,比如用系统生成整个植物或者奇怪的生物、用噪点生成整个地形,或者用一系列的标记点生成文本。但这里有一个问题:你该如何将这些程序生成技巧融合起来,区打造一个大规模的生成系统?
很明显,大规模是一个相对的概念,但我们今天所指的是任何可以让你将多种技巧以创新方式结合起来的系统。
我们是来自 Games的两名创始人,Jason 和Brian 。我们做了一些游戏,比如《》以及《Caves of Qud》。几年之前,我们曾在《游戏设计里的程序化生成》一书里写过几个章节的内容。几年后,又有一本书叫做《游戏设计里的程序生成剧情》,我写了一章,主要讲程序生成的历史,也是我们今天要说的一部分内容。
如果没有听过《Caves of Qud》这款游戏,我简单做一个介绍:这是一款开放世界科幻RPG和游戏,游戏的宣传语是“凿开前年文明的一层蛋糕”。我们做了一些手工制作的剧情和一些模拟系统,还对程序生成做了拓展运用,这也是今天的主题。
今天的主要内容就是通过《Caves of Qud》程序化生成的城镇案例来解决开头提到的问题,我们尽量将内容提炼为通用的常识,但主要的方式还是案例分析,所以至于怎么根据自己的项目合理利用,还需要大家自行探索。
游戏设计背景
策划背景是很重要的,因为每当你打造一个系统,甚至是任何一个系统,都需要了解策划背景,因为这会影响到后续研发的大量决策。
比如我们要做的是一款RPG,所以选择了模拟方式的游戏设计,这句话的意思是,城镇是真实存在的事物,我们试图模拟它的动态,可能不够真实。在这个城镇里,玩家们对它的理解是通过自己的角色形象,与NPC的对话等等。
这与经营类的《模拟城市》系列不同,你不需要知道一个城镇500年来发展的系统问题。因为我们做的是一个RPG,所以玩家只能用这种方式体验。我们很看重输出内容的创新,所以用不同模块给了程序生成器很大的自由度。
模块化设计非常好,从游戏软件设计角度来看,分离的模块很容易处理,使用起来很灵活;但是从游戏设计角度来说,模块化也非常好,因为这些模块可以组合成大量不一样的形式,并且带来创新的内容输出。
这是日本富士山,但今天我们称它为“抽象山”。虽然这个比喻有点傻,但的确对今天要说的内容有些帮助。我们比较宽泛的目标是用模块化的内容打造出真实的山谷,做出让玩家真正能够体验的内容。
我们的大致方法是,通过多个步骤生成一个城镇:用多种抽象画的概念将城镇模块化,一开始的模型会很抽象,随后用数据输入,让它变得更真实。相反,如果有时候必须做一个比较真实的决策,那就用默认数值。
今天说的内容并不会对每一个模块深入探讨,首先是没有那么多的时间,因为一个个的详细拆解会很耗时间,另一个原因是,这些模块很简单,只要稍加研究就能知道怎么回事,有些复杂的我们会提到。
这是《Caves of Qud》里的城镇地图,有很多内容,内层建筑被外层建筑环绕,有大量的们、村民,右下角还有像图书馆和书店式的建筑,右上角还有厨房一样的建筑。这是最终结果,我们将逐步分解它是如何得来的。
需要先确定的是,一个城镇都包括什么?城镇是一个全世界都知道一些的概念,但《Caves of Qud》的设定离现在很遥远,所以古代世界给我们带来了大量的灵感。我们差不多有10年没有做过这类游戏了,所以只能试图将之前做过的游戏拆解,然后用程序生成方式将自己的想法做出来。
首先最重要的是村民,就像很多RPG游戏一样,他们是不同的NPC。我们还想要生成一些历史,城镇还要有地理位置、建筑风格,有管理者/政府、文化习俗、宗教,要提到本地资源之间的关系,还要有装修风格、食物与饮品。
我们为NPC设计了对话,所以有时候他们会根据自己的历史说一些谚语,最后是一些收集物和个人需求,我们像很多RPG那样把它做成了任务的形式。
这是我们在多层系统设计中用到的一些技巧,后面具体分析的时候,我会提到一些技巧的名字,但这里只是专门列出来,并不会按照这顺序来说。
在《Caves of Qud》当中,城镇生成分为三个阶段,这里主要说后两个阶段,然后简单说一下游戏设计阶段。
每当设计一个城镇的时候,我们都想要带给玩家全新的世界,所以这个过程被称为世界生成阶段,实际上就是生成这个城镇的各方面历史,随后会进入解析邻居的阶段,比如城镇所处的位置以及它和周围城市以及NPC的关系。
世界生成之后,你有了一个角色、一个可以探索的世界,但这时候很多细节都没有确定,我们会根据游戏需求进行细化。这就是制作阶段,我们会根据历史生成文化、建筑风格,然后将墙壁、角色放在对应建筑里。
程序生成五步走
第一个阶段是游戏设计阶段,这是很抽象的过程,比如我们会用很多的表格、蓝图等确定生成的目标。
这里列出的5个步骤,刚开始是很抽象的历史,回到刚开始的话题,由于我们要生成的是一个很具体的模型,玩家只能通过探索世界、与NPC聊天等形式了解游戏剧情,所以这个城镇的历史生成非常抽象化,随后会生成更具体的内容,最终做到让玩家真正体验的世界。
这是一个城镇当中的纪念馆截图,它将作为试金石,拓展到我们要说的整个系统。我们看到纪念堂一样的建筑,角落里还有火炬柱,中间还有各种纪念碑。里面的任何东西都可以互动,而且还可以看到不同物体的描述:
790年,Nawan的市民决定让市长退位,并在镇里废掉所有的等级制度。因此Nawan市民生活的两大主题就成了无政府状态的价值观和传说中的巨型蜻蜓,比如图中的右侧还有一个蜻蜓雕像,也是镇子的一部分。接下来说说,我们是如何从生成历史,做到了这个具体的纪念堂以及很多东西的描述。
这张图说了很多东西,左侧是一系列的输入,这里会从生成历史开始;右侧是内容输出,可以看到有五个步骤,开始是生成历史,结束是制作游戏目标。实际上这与我们开头说的三个阶段有关,比如前两步是世界生成阶段,后两步是制作阶段。
1、生成历史
左侧是动态输入,首先是世界种子阶段,它决定了后续的大致内容。左下方是设计输入,是在游戏设计阶段加入的,比如游戏里的阵营、区域、文化关系图等。对于这个图表,大家没有必要理解具体的每一步,它只是我们讲述世界生成的一个工具,如果有重要的东西,我们会特别指出来,但不用特地记住每一步。
比如在阵营方面,有羚羊、类人猿、蜘蛛等,每个阵营都有自己的喜好和行为习惯。
文化关系图可能看起来比较混乱,我们用代码的方式将关系图做出来,并且用文字将它们之间联系起来,可以生成对话,然后不断重复利用这些步骤。
所以,我们在生成历史的时候,会输入很抽象的内容,比如城镇名字、基本的阵营、历史事件的描述、政府、可怕的事物、世俗的食物,以及明显的特征、食物等。由于很多具体的内容留到以后制作,所以这里很多东西都是非常抽象的。
比如在城镇历史这里,你们可以看到所有都是一些关键数值,比如镇子名称、市长等等,都是一串串的字符。
我们有一个事件逻辑,决定一个事件何时开始、何时以及为什么结束。比如一个村民开始崇拜周围的生物,选定之后,我们会生成一些文本描述该事件,然后基于现状来解释事件为什么会发生。
如果想要了解具体的历史生成模块,我此前也做过一次GDC演讲,题为“Caves of Qud里的程序生成历史( in ‘Caves of Qud’)”有兴趣的读者可以参考。接下来是解析邻居阶段,这个阶段主要由Brian来说。
2、解析邻居关系
Brian:前面Jason提到,我们输入了很多抽象的概念,比如村民崇拜生物,但这个阶段,他们甚至不知道崇拜的生物是什么。他们崇拜生物这件事情很有趣,但我们需要将其具体化,这就需要谈到周围邻居的设定。
首先是这个镇子在世界中的位置,我们做一个世界地图,然后会在其中为这个抽象的城镇找到它的位置。
《Caves of Qud》的世界地图是静态的,有不同主题的城镇,比如沙漠风格、丛林风格以及山脉风格等等。但是,玩家们每次开始游戏的城镇都是动态的,所以静态的世界地图是基本支撑点,它容纳了所有的程序生成内容。
除了静态的地图之外,我们还对很多内容做了设定,比如丛林是什么类型、遭遇的是什么样的敌人、播放的背景音乐是什么…等等。
做城镇的时候,我们首先会确定它到底是个丛林城镇还是高山城镇,然后在地图上为它找到一个位置,比如是为了纪念神羊而在很高的地方建立的城镇。此外,我们还做了一系列其他的东西,比如奇怪的生物、鞋匠等等,分布在世界各地。
接下来,我们会进一步细化城镇历史,将抽象的历史与细节历史融合。比如城镇会和传奇生物联系在一起,如果确定了一个生物,那么我们可以在周围不远处找到其他相关的城镇,你就有了比较具体的历史关系,我们所有的抽象关系都是这么具体化的。
这是实际的数据,开始是崇拜某一个传奇生物,这样的标签很简单,随后我们会对其具体化。比如传奇野猪Kheli Ufeat,就与具体的城镇相关。比如每一个城镇都会增加一个阵营,并且确定它与别的阵营之间的关系。
这时候,所有抽象化的历史就都做完了,我们已经打造了一个静态化的世界,玩家进入游戏之后,就知道世界大致的概念,随后我们就要进入具体的内容制作,比如开始文化的生成。
3、文化生成
Jason:在生成文化的时候,上述所有的抽象输入都是有影响的,比如丛林文化与沙漠文化有截然不同的差别。我们使用人口图表和文化关系图来生成文化,并且会分成多个步骤来做。
比如在剧情叙事方面,Nawan的人们喜欢用建造纪念堂的方式叙事,还有些地方喜欢用刻字的形式,比如喜欢将历史事件刻在土灶上。
有的城镇喜欢把故事放在墓穴里,比如放上书架,你可以找到历史第二卷,了解这个镇子的历史。
随后,我们会用随机的方式给某个文化确定不同的数值,比如上面这张表。不过,我这里更想说的是在程序生成过程中,我们使用的工具,比如上面的人口图表。
比如每个条目都有值,门是20,纪念碑是40,它的意思是,村民通过纪念碑讲故事的概率是门窗、绘画、家具等方式的2倍。
随后,我们还可以在的基础上增加中间值,给它们更为具体的意义。比如下图是一张丛林生物的图表,随机选择一个值,然后根据数字确定具体生物。不过,更关键的是最后几行,与之前单个选择不同的是,这里是全选,数字1-2得出的生物是,然后你有50%的概率遇到播种者、50%概率遇到,还有10%概率遭遇。
这是一张家具表格,讲的是苹果商人帐篷的设计。比如火炬柱的数值是1-2,如果数值为2,它就被放在门外,Woven 被放在内部的某个角落,这些是我们生成家具位置的表格,在世界生成的时候,这些数值就会决定某个家具在不同地点的位置。
说到文化生成,我们也非常注重各地的特色事物,比如每个城镇都有各自著名的食物,每一种食物都有不同的效果,比如给角色带来某些效果的抵抗加成。
在玩家与不同阵营的关系中,你可以用声望来交换食物制作方式,这也进一步影响到了玩家在游戏里的行为。
4、建筑生成
Brian:你们可能发现,经过了上面的三大步之后,实际上我们还没有做任何真正的游戏资源,因为这就是我们的目标,我们想通过抽象化的输入,来实现真正的游戏内容输出。所以这是我们真正做内容的第一步。
不过,在开始制作之前,我们还需要根据之前的输入,做一些重要决策,比如建筑风格、重要建筑、农作物、装饰作物、野外植物、门窗风格以及墙壁类型等等,这些都是非常细节化的内容。
做一个城镇的时候,我们会去掉所有的生物和角色,逐个确定细节。比如在建筑风格上,根据所处区域的不同,左侧的鸟类以巢穴为主,右侧的鱼类则主要生活在水池里。
重要建筑这个可以回到纪念碑的那个案例,如果村民崇拜某个生物,并且喜欢用纪念碑的方式叙事,我们就会打造一个具体的纪念碑。所以,我们会逐个确定这些细节,然后为每一个城镇找到答案,这样就有了各种物品的位置摆放。
随后,我们根据地图上的位置,选择WFC表格里的图形,然后放在地图里。
比如图中的下方是帐篷,右上方是绿色建筑。
然后,我们还要更进一步,因为要知道建筑里的是什么、建筑外的是什么。
这样就有了大量具体化的建筑和布局,这里是一些具体的案例,到了这时候,我们就可以为游戏做具体内容了。
5、制作具体内容
Jason:每一个物体都有一个蓝图,也就是物体的具体参数。
比如在火炬柱制作之前,我们要先确定它的颜色、渲染值、物理效果等很多细节。
具体的案例还是纪念碑,我们确定了纪念碑的位置、形状和具体参数,但我们并不是简单的具体化制作,而是动态化的选择,比如我们会将某个故事与某个纪念碑结合起来,所以这里有很多的故事,你看了纪念碑就能了解城镇的历史。
游戏里所有的城镇都是按照这五个步骤生成的,具体做游戏内容的时候,比如山羊,它也是市民的一种,有自己的行为习惯,身上还带有图腾,讲述的是Dabal城镇的历史。
有些内容是与背景有联系的,比如为什么某个阵营喜欢用图腾讲故事?还有些时候是没有原因的,这时候我们就会随机选择,因为历史中的任何东西都没有影响这个物体,所以自由度就更大一些。
还有些对话和任务生成,细节可能会比较复杂,但大致也是根据之前的城镇历史决定。比如在知道了具体位置之后,你可以确定某个城镇的植物喜欢什么,任务描述里就有这么一句:这个地方可能会有什么珍宝?二氧化碳?充足的阳光?还是联系摔角的圣地?我们必须知道。
总结
在一开始的时候就要认真考虑设计背景,真正推动程序化生成的是你的策划目标。模块化会让你的城镇生成更加简单,然后当这些模块组合在一起的时候,会给游戏世界带来更多的新内容。
游戏里的历史很抽象,所以你可以充分利用这个优势,然后决定这些模块的参数,以便随后可以使用。如果你没有很好的决策或者不必设置具体参数,使用生成器默认的数值就可以。最后就是做一些比较实用的工具,比如我们做的人口图表,这节约了大量的设计时间。