首发于 我做游戏这几年

从游戏设计角度看基于组件的游戏开发方式

写在前面

2022年虎年假期在百般不情愿下,还是结束了。不知道同学们这个假期过得怎么样?
老李我今年春节除了必要的走亲访友和休闲娱乐以外,空闲时间基本都用来折腾godot这个游戏引擎了。
最开始只是抱着尝鲜的态度试着玩儿了两天,没想到这个只有几十兆的游戏引擎异常好用(我只要使用2D部分)
以至于我已经很久没有启动Unreal引擎了(启动一次确实也比较慢)
未来一段时间我应该会更多精力在godot这款引擎上,争取创作一批项目实践课程,感兴趣的可以关注一下。

我(游戏策划)所理解的基于组件开发

注:以下内容只作为我作为一名游戏策划,而非专业的程序开发人员的主观理解,如有错误欢迎批评指正,不吝赐教,我将虚心改正。

很多文章会将面向过程、面向对象和面向组件开发相提并论,难免有混淆是非之嫌。
面向过程编程和面向对象编程是一种编程范式,很多编程语言在语言层面采用这种编程范式,因此在使用这些语言时需要时刻考虑面向对象的编程原则,也因此产生了很多基于面向对象的设计模式
面向对象试图将世界中的对象抽象归类,关于面向过程与面向对象的异同我们这里不过多论述。
事实上面向对象中就有“组合优于继承”的设计原则,进而上升到软件工程的层面,就成为我们今天所说的“基于组件开发”

回到游戏开发这个场景下,
面向对象试图将游戏对象归类,比如猫、狗,然后再给这些类型赋予能力,猫能抓老鼠,狗能看家护院。
但具体到实际游戏开发场景中,可能我们需要一个可以抓老鼠的狗。这时候我们开始发愁要不要让狗继承猫这个“父类”
我们发现随着电子游戏的发展,游戏规则的复杂导致开发者不得不考虑比继承更合适的代码组织方式。
如果引入类似CPP中的多父类继承,大概率会使代码结构混乱,难以维护,导致开发人员付出成倍的心智负担。

基于组件开发


类似这种问题变多之后,静态类型语言创造出接口Interface这个概念,来满足这种需求
动态类型语言方面,因为其动态特性则灵活的多,也就是我们所说的“鸭子类型”:如果一个对象能游泳,能发出鸭子叫声,则可以认为这个对象是鸭子。
当然,这种灵活性也要付出代价,这里我们也不多谈。
更多人意识到此类问题,并尝试解决,于是google推出了golang,试图在语言层面解决一些工程问题,其中就包括上文提到的接口interface
golang中的接口interface究竟有什么不同,我们这里依然不展开讨论,但到此为止,我们可以理清编程语言的发展历程
编程语言的发展一定不是人为的主观干预,而是面对实际的工程问题时的自然演化。
理解了这一点,再看后来的基于数据开发、面向服务架构等概念就不会感到摸不到头脑了。

主流游戏引擎中的应用

在主流商业引擎上,Unity3D毫无疑问是最优秀的基于组件开发的游戏引擎。
这也是Unity引擎迅速占领游戏研发市场并且迄今为止仍占有很大市场份额的原因之一。

Unity游戏引擎


Unity引擎中,游戏对象被抽象为GameObject,但GameObject并不包含逻辑。而是作为若干个Component的集合体。
Unity引擎为我们提供了部分Component,而开发者也可以很方便的创建自己的Component来自定义游戏逻辑。而引擎则提供了方便的增删改查Component的方法.

Unity引擎截图


多个GameObject可以组装成树状结构,并序列化为Prefab(预制体)保存在硬盘中,在后来的版本中,Unity还提供了Prefab编辑器。
可以说组件ComponentUnity引擎的基石。

Unity引擎的成功很有启发性,以至于Unreal4引擎也紧随其后宣布支持组件。
Unreal引擎的问题在于它作为拥有多年历史的老牌游戏引擎,这里表现出“先发劣势”

Ue5虚幻引擎


Unreal引擎积累的很多实用功能的同时也保留了很多臃肿的代码内容,
以至于·Unreal·不得不在保留了面向对象编程的前提下同时支持组件。
这就导致开发者在编写游戏逻辑的时候同时要考虑这个游戏对象是什么和有什么,以及一段逻辑应该写在组件中还是采用继承的方式这类问题。
Unreal引擎官方的说法是蓝图blueprint类比于UnityPrefab,但熟悉二者的开发者应该都明白其中的差异。这里也不展开来讲了。
不过话说回来,Unity中依然有将继承思想引入Component中的编程方式,
直接编写一个Cat猫的组件赋予Gameobject这种也属于常规操作,
因此究竟应该如何组织代码也算是见仁见智的事情了。

而到了我最近这段时间研究的Godot引擎上,则更为纯粹或者说激进的——整个游戏组织成一个Node Tree节点树,
可以说godot引擎是基于节点开发的游戏引擎。玩家可以通过继承现有节点来编写自定义节点。也可将继承自节点的脚本挂在节点上。

godot游戏引擎


通过继承的方式实现节点的功能扩展。为了对节点树实例化,godot提出了scene的概念。
我主观认为godotscene概念并不准确,应该直接叫node_tree更准确一些,因为可以有别于Unity中的SceneUnreallevel的概念
godot官方对于scene的解释是类似于Unity中的sceneprefab
仔细想想Unity中的sceneprefab又何尝不都是对于GameObject tree的序列化方案呢?
虽然godot中的node依然和unity中的component有一些细微差别,但其本质上都是对于“组合优于继承”这一涉及原则的开发实践。

很难主观判断孰优孰劣。

市面上已知游戏的应用

Klei Entertainment 开发的《饥荒》为了获得更好的mod制作能力,而将包括游戏脚本Script在内的多数游戏资源公布给玩家。

《饥荒》


让我们得以窥见这款游戏的逻辑代码是如何编写的,让人惊喜的是,其使用的基于组件的开放方式。
《饥荒》使用lua作为其脚本语言,得益于lua动态类型脚本语言的特性,因此很容易实现基于组件的开发,因此我们发现除去一些AI因为逻辑相对复杂的原因而采用了状态机和行为树,以及一些通用的或者框架类的脚本,其他脚本都被抽象为component
《饥荒》中引入一个prefab 脚本 的概念,在这个脚本中完成一个 gameobject的“组装”,这个过程包括资源文件和逻辑组件。
但并不是说《饥荒》中基于组件开发的实践就是完美的,component和prefab之间以及component和component之间使用标签、事件和回调通信,
这事实上已经不能满足我们一直强调的“高内聚,低耦合”的原则,依然要在prefab中处理大量的component回调。
但我们依然可以借此,来理解我试图表达的含义。
《饥荒》的开发者们,甚至我们mod制作者(很多非专业游戏开发者的玩家)可以很容易通过组合现有component来创建新的prefab
这种思想尤其适用于《饥荒》这类核心玩法在于处理游戏世界中各类对象的游戏。

《缺氧》


Klei Entertainment 后来推出的《缺氧》,作为一款资源整合类游戏,可以说从根本上就适合这类基于组件(甚至是基于数据)的游戏开发方式。

基于组件引发的游戏设计思考

但我这里更多还是想从我的身份——一名游戏策划(或者说游戏设计者)的角度谈谈基于组件的开发方式,
因为这和后来提到的基于数据开发(ECS可以看做是一种实践方式)有着不谋而合的共同点。

虚幻引擎ue5演示截图


在游戏设计领域,随着开放世界游戏的兴起和火爆,近年来最热的概念应该就是所谓的“涌现式设计”了
了解我的同学应该知道,我主观上很反感所谓“涌现式”这种略显“事后诸葛”的设计方式。
更大的原因是很多从业者将涌现作为其设计漏洞的遮羞布,这个我们未来有机会在讨论。

但我也在思考,在开放世界游戏中,有别于传统线性叙事游戏。这类游戏要到达的其实是一种重复可玩性。
这种重复可玩性来源于两部分:空间上的(关卡)和时间上的(叙事)
空间上的很好理解,很多roguelite游戏已经在这方面探索了很多,但开放世界游戏并不能随机地图,或者说只能在小范围内随机关卡。
随机关卡的另一部分表现就是随机敌人或者随机谜题,进而衍生出随机属性,这部分可以参考暗黑破坏神为代表的装备词条系统。

《暗黑破坏神2》


叙事上的随机近年来也有很多尝试,从早几年的《环世界RimWorld》,到最近这段时间的《漫野奇谭》我也在关注
当然,类似《十字军之王》、《太吾绘卷》这类策略游戏中也会有一些随机事件。
这类随机事件如果设计合理会大大增强玩家的游戏代入感,但如果设计不够严谨则会破坏游戏的角色扮演氛围。

塞尔达旷野之息

这里我想说的是,作为游戏设计师,在面对诸如开放世界游戏这种如此庞大、复杂的游戏系统时。
如果依然是着眼于游戏内的某个系统,将其作为相对独立的部分,势必导致整个游戏被割裂。从而影响玩家的游戏体验。
这实际上就是在用面向对象甚至是面向过程的思路在做游戏。这种思路在面对休闲游戏、传统单局制游戏甚至MMORPG游戏时都不会产生多大问题。
但在以开放、自由度为卖点的开放世界游戏中,则会产生浪费。
那么如何以基于组件的思维来设计游戏呢?其实上文中已经给出答案。

期待godot引擎4.0版本的发布


从关注一个游戏对象是什么,变为关注一个游戏对象能做什么?
以游戏内道具为例,我们不在给道具下定义为装备、消耗品、材料或任务道具这些。
而是赋予道具能力:可装备的、可饮用的、可作为合成材料的。然后再针对每一种能力编写具体的功能逻辑。
这就从游戏的设计层面、或者说软件工程层面支持了“玩法涌现”的可能性。否则所谓”涌现式设计“只能是空谈。

两个鬼故事信用卡之窗小猫起名字卧薪尝胆电视剧心乱如麻造句中国南方航空官方网站扫黑风暴网盘资源给儿子起名网站战士宏公司保密制度睿字和甚么字搭配起名兽兵卫忍风帖猪宝宝起名网免费取名字你却爱着一个傻逼安卓应用商店都市小道士告诉你一个我的故事男宝宝起什么名好男孩用安字起名大全周易免费起姓名周姓起名最好最吉祥的名字大全通讯地址怎么填男宝宝起名姓于大北农股票属猴怎样取名起名大全起名哪位大师书名号和句号一起怎么占格周易起名 方法五金公司起名太极1从零开始男生谢氏起名大全少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

两个鬼故事 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化