所有事情都有成本,程序员决定哪些成本值得支付——我在 Skypjack 的博客文章中读到这句话,当时我正在研究如何在 C# 中实现一个好的 UI 框架,这显然仍然是一个问题,但让我们将这次讨论留到另一天。然而,这句话却时不时地在我脑中闪现。
讽刺的是,旅程本身始于我读到那句话的许多年之前。我成长于一个没有 YouTube 教程、没有专门的游戏开发课程和没有商业引擎的时代。如果你想了解游戏的一部分是如何工作的,你必须购买一本书或自己构建它。这正是我所做的。
我从来没有期望完成我的引擎。它是我的个人游乐场——一个地方来观察运动的部件、学习、实验和偶尔犯下疯狂的错误。回顾起来,游戏开发一直是我的动力,而好奇心一直是燃料。每当我遇到限制,我通常会问为什么某样东西是这样做的。
构建构建器
随着引擎的发展,维护它变得比编写它更困难。我必须在不同的机器和 IDE 之间切换,这涉及维护巨大的 Visual Studio 解决方案或同样巨大的 Makefiles。对我来说,两者描述了相同的项目,但以不同的形式。就在那时,我发现了几个强烈影响我的思维的想法:一个小的 GitHub 项目、关于约定优于配置的文章,以及 Unreal Engine 的构建工具 UBT。
经过三次重大修订后,这些实验进化为我的 SDK。尽管游戏和引擎不断增长,尽管被称为模块化,但大多数引擎仍然依赖于一个不断膨胀的核心。我开始思考一个引擎是否可以从许多小巧的、专门的模块中组合起来,并以最小的引导程序的形式分发,只下载项目实际需要的内容。所有这一切都变成了 Hecate,我的个人构建工具。
当一个解决方案创造了下一个问题
构建系统解决了一个问题,但立即暴露了另一个问题。常规表达式不再足以了解现代 C++ 项目,我最终实现了一个完整的 C++ 预处理器。这反过来又使静态分析和 linting 成为几乎副产品。同时,感觉需要图形工具的需求就像下一个大事一样。
C# 是决定一个好解决方案的难题。WinForms 不够灵活以实现我想的内容,WPF 将我绑定到 Windows,web 框架感觉过于沉重。通过搜索替代方案,我发现了反应式编程。在同一时间,我遇到了 Skypjack 的 ECS 博客。尽管它们来自不同的领域,但两者分享了相同的基本理念:让数据驱动行为,而不是将行为紧密地耦合到对象中。这成为了 缺失的 puzzle piece。
从数据到执行
一旦所有事情都变得越来越数据驱动,另一个问题出现了。一个工具为什么要存在于命令行应用程序或图形应用程序之间?我脑海中最大的转变是当我对 Linux 和最终 Linux 内核产生了越来越大的兴趣时发生的。它的架构让我着迷。内核模块不以任意方式互动。它们依赖于内核暴露的能力,而与其他模块保持着相当大的独立性。
在某个时候,我意识到同样的原则也应该适用于游戏引擎。一个游戏引擎最终是游戏执行的操作系统。一旦我开始通过这个角度看待引擎,许多长期存在的假设就不再合理:
- 为什么游戏逻辑是永久编译到引擎中?
- 为什么模组和第一方功能是完全不同的?
- 为什么系统是以 OOP 为中心的方式耦合在一起,而不是通过数据流和实体进行合作?
这些问题成为了 新 SDK 和一个能力驱动的架构模型的基础。
重思考开发的成本
最后一个影响来自一篇关于 Deck13 的 Fledge 引擎的旧文章。他们的哲学简单:程序员提供可重用的动作,而设计师从这些构建块中组合出游戏逻辑。我一直在思考这个想法可以推向多远:
- 如果这些构建块变成反应式数据流?
- 如果 ECS 变成执行模型?
- 如果所有事情都可以可视化并翻译为不同的编程语言和平台?
这些问题最终变成了 SDK 和 新引擎架构 的第三部分;一个 数据驱动的编辑器 作为主要开发环境。
伴随着仍然存在的 UI 框架的需求,我开始看待 web 浏览器以不同的方式——不仅仅是一个 web 应用程序的平台,而是一个开发工具的渲染引擎。浏览器渲染界面,而一个本机应用程序通过一个轻量级 HTTP 服务器暴露其功能,保留了轻量级的性质而不使用沉重的 web 框架,同时利用了每个操作系统都有的标准浏览器: 基于浏览器的 UI 运行时。
下一步发生了什么
SDK 感觉更像是一个目的地,而不是一个目的地。它更像是一个速度从自行车转换为高速列车的地方。
我还发现了许多基本思想不再像以前那样显得不寻常。Epic 正在向 Verse 进行移动,并将 Unreal Engine 6 描述为一个更动态的运行时,整个行业似乎正在探索许多相同的问题——尽管当然不是相同的解决方案。
如果这个旅程引发了有趣的讨论或激发了您对不同的方法的思考,那么这已经超过了我最初的期望。然而,让我知道您是怎么想的!
评论 (0)