阅读 108

【GDC笔记】Baba Is You 技术分享观看笔记

试用下掘金,markdown编辑器也有了挺好的......之前跟面试官聊了下未来的发展,大概有了点突破瓶颈的方向了,决定一边增强输入一边刻意复习基础知识,最近有空了会看看GDC,觉得有意思的会写个博客记一下啥的~(下面的内容是从原来用的平台粘过来的,懒得重新截了,希望不要制裁我QAQ,好用我就直接在这写了)

基本信息

原视频链接(油管)

玩法

Gameplay的话,主要是通过推箱子(单词)改变世界的规则来让自己通过关卡,这么一个解谜游戏。大概看看预告片就能知道最核心的体验了。(我脑子不太行反正是没法继续玩下去的...)

系统基础

显然这么一套逻辑就是依赖于规则系统,通过将句子翻译成程序可理解的规则,来作用于游戏中。每条规则都至少含有三个基本要素:Baba(对象) Is(动词) You(性质,当然也可以是一个对象). 第一个要素描述了这条规则作用于谁;第二个要素描述了这条规则如何作用于这个对象;第三个要素描述了这条规则具体的影响是什么。 所以最核心要解决的问题就是如何将游戏里由玩家自己组的句子翻译成可读取的规则。

其它信息

开发者Arvi Teikari 是一位来自芬兰赫尔辛基的游戏开发者。Baba is you最初灵感来自于一场game jam(也取得了很好的成绩),那个时候整个游戏的规则和系统都特别简单,后来多次迭代之后慢慢变得更加复杂。游戏使用Multimedia Fusion 2引擎,发布于2019 年 3 月 13 日,平台是pc和switch,迭代了两年左右。

实现

开发者称绝大部分逻辑是用Lua写的,并且强调了lua的table的特别。(我自己比较熟悉lua,贴个官方文档table那一章节,总之lua的table特别灵活自由...挺野的语言...)

句子->规则 翻译过程

问题

整个关卡中句子无处不在,有些可能能组成有意义的句子,有些是无意义的句子,有些单词挨着但不能组成称得上句子的东西,有些单词孤零零的在那里放着......所以需要一种句法分析方法来找出符合逻辑的有意义的句子,再将它背后的意义(规则)以某种方式存储下来。(图片均来自于GDC原视频截屏) 开发者给出的例子,之后的分析过程也会沿用此关卡

解决方法

这里先不考虑以什么格式存储规则(那是下一部分的内容),仅仅考虑句法分析。简单的来说就是筛出那些有意义的句子。开发者最后采用的解决方案是使用multiple passes. (多遍处理,有点编译原理内味...) 下面的开发者给出的例子只包含很基础的游戏中“语法”,实际上的应该更加复杂,但原理是一样的,只是再第二遍和第三遍的处理逻辑会更加复杂。

第一遍

第一遍的意义是找出所有可能的句子,不需要考虑语法和语义,只做很简单的筛选。 首先游戏里的句子只可能是从左到右和从上到下的,所以有可能成为句子中第一个单词的只可能是上面或左边没有其它单词的单词,再加上一个句子至少包含3个单词,所以所有少于三个单词的句子也不可能是我们想要的有意义的句子。这样可以很容易的筛选出可能的句子,程序上也很好实现。图里框出了这步筛选的结果。 first pass

第二遍

第二遍相当于是语法检查,会检查上一步筛选出来的句子中每个单词的类型。(事先定义好的,比如说baba是一个对象,is是一个动词之类的...) 这一步非常关注单词的类型,会把每个句子过一遍,检查是否符合语法规则 (Object Verb Quality),如果遇到不符合语法规则的,比如有这么一句话Baba Is You Rock Is Push(这句话跟图中的例子没有关系,是另外的小例子),处理到You Rock的时候会发现并不符合规则,那么我们获得了已有的一句Baba Is You,然后从Rock开始继续往后面分析,发现Rock Is Push也是符合语法规则的句子。这样筛选出来的结果也在图里框出来了,还剩下三个可能能产生规则的句子。 据开发者所说,这一步是最最最复杂的,因为后面新加的复杂类型的单词让这步越来越复杂。(想想编译原理里的语法分析也比较复杂,但至少定义的比较清晰,可以有一个语法树,个人觉得像这样的自然语言确实更棘手一点) second pass

第三遍

相当于语义检查,这一步检查句子是否有意义(能产生规则),并把规则添加到游戏逻辑中的全局和局部规则表中。(存储格式在下一部分讲到) 这一步的逻辑还算简单,比如在这个例子中,Has并不接受Win作为它的下一个词,所以扔掉这个无意义的句子。然后只需要以某种格式将Baba Is You和Rock Is Push这两条规则存下来,在游戏逻辑询问时能读取到就可以了。 third pass

其它需要处理的情况

开发者最后还分享了一些其它需要注意的地方,比如单词分组(主要是在处理带参数的条件语句的时候,比如Baba on grass is you这种)、能产生其它规则的规则(All is you)、能禁用其它规则的规则(Baba is not you. 在这个游戏世界里not的优先级是最高的,跟编程语言的not是一样的感觉)、规则变化时动画和音乐的播放等。

规则系统的存储

Arvi在分享中详细分享了规则系统的五次迭代,随着游戏玩法愈发复杂,在旧的系统中开始出现越来越多的特殊处理,于是必须或大或小的做出调整,这么迭代了五次,得到了一个基本可以满足现有需求的稳定的系统。(还存在一些问题,他表示会努力fix) 我这里只把他的最后一次迭代成果记在笔记里,感兴趣的可以看看原视频,很好的。 需要说明一下的是图里的框对应lua里的一个table,很好懂,简单解释一下就能明白。 current iteration 直接单条规则的结构。Rule Base包含最基本的语法,从中可以得知这条规则会如何影响到某个对象。Conditionals里包含若干条条件(也可以没有),比如第一个条件是On Grass,参数可以没有(比如Not不需要参数),可以有多个(比如On Grass And Flower)。Word IDs跟规则系统核心没什么关系,记录的是如何找到Rule base里同索引的东西在游戏里的object。(方便调整相关视觉效果)

其它难点和问题

Arvi在这后面还分享了很多在现有体系中无法解决的问题或已解决但很复杂或可能有bug的问题之类的,蛮有意思的,还有一些反思与总结。因为基本是在抛出问题而不是解决问题,我就不想记在笔记里了,但是很有趣~

其它

看完一个小时的分享让我疯狂回忆编译原理课...词法分析、语法分析、语义分析、中间代码生成、代码优化、错误处理......结合起来想想觉得还挺有意思的。