展开引擎代码概述

2020-12-31 02:06:50

我们有时会遇到有关Defold游戏引擎运行时如何在某些区域工作的问题。而且,由于我们也接受对源代码的贡献,因此我认为是时候对该引擎的结构进行一些深入了解了。我想从一个较高的层次开始,描述更大的系统,然后在以后的文章中,详细介绍一些关键系统。

正确描述一个详细描述游戏引擎中所有依赖项和库的图形将是一项艰巨的任务,因此我将对其进行更深入的概述,该图试图在显示所使用的系统以及一些关键库之间取得平衡他们使用的。它还尝试传达一种“层”的感觉,其中顶层取决于底层的功能(但绝不反过来)。

在基础级别上,我们具有为其他库和系统提供核心功能的库,例如C ++容器,线程支持,网络支持,加载/保存文件和数据格式。

这种格式是在Google Protobuf之上实现的。我们生成到C ++,Java和Python的绑定,这些绑定将在我们的工具以及游戏运行时中使用。

引擎支持(安全)套接字,我们在其上构建套接字以实现http(s)支持。这允许游戏请求信息或存储游戏会话信息,例如用户信息,高分等。

我们在引擎中使用了几种类型的压缩。我们向开发者展示ZLib deflate(用于解压缩自定义文件),并使用LZ4压缩游戏档案。对于纹理,我们还可以选择WebP。

对于基本的哈希函数,我们使用很小的MurmurHash2A,并且可以很好地实现我们的目的,我们使用它对短字符串和文件路径进行哈希处理。它也可以在生成游戏对象时为它们生成唯一的ID。我们存储哈希状态(uint32_t)供以后使用,这使我们可以递增地哈希更多数据。

哈希也存储在保存游戏中,这是我们尚未将哈希函数更新为任何较新版本的原因之一。

我们在引擎中仅使用几种类型的C ++容器:数组,哈希表,对象/索引池。它们不是“现代C ++”,并且已实现为支持POD类型。

我们已经支持OpenGL已有一段时间了,但是最近我们增加了对Vulkan的支持。这种过渡相当简单,因为我们已经拥有了自己的图形API和OpenGL后端。目前,我们的图形API面向的是OpenGL的工作方式,但稍后我们将添加更现代的API,以反映Vulkan后端的更新功能。

渲染本身是通过向渲染器发出命令来完成的。例如。清除或绘制。Draw命令使用一个谓词,该谓词用于收集具有与该谓词相匹配的材质的所有渲染对象。一旦所有匹配的对象都被收集,请计算一个“渲染键”,该键用于对具有相似谓词的对象进行排序特性。这使我们可以将相似的对象批处理为一个绘制调用。

请参阅“订购图形绘图电话!” Christer Ericsson撰写的有关批处理密钥的更多详细信息

Defold最强大的功能之一是渲染管线可编写脚本,它允许开发人员通过清除渲染目标,设置材质,设置相机矩阵,进行多次渲染传递等操作来控制渲染帧的流程。

我们的声音引擎很小,没有很多功能。它支持多种声音和组,不同的速度和声像。支持的格式为Wav和Ogg。取决于平台,后端是OpenAL,OpenSL或WebAudio。

我们的输入分为两个库:HID和Input.HID是硬件抽象,而Input是高级处理。

由于遗留原因,我们在香草引擎中有两个物理引擎(Box2D和Bullet 3D),随着我们正在努力将越来越多的功能转移到引擎的单独扩展中,这可能会在不久的将来改变。当前在主线程上进行了更新,这也是我们将要进行的工作。

扩展是引擎中某个api的实现。在这种情况下,我们指的是与应用程序生命周期息息相关的实现,这些是当前可用的功能:AppInitialize / Initialize / Update / OnEvent / Finalize / AppFinalize C ++,Objective-C或Java。

我们正在不断地努力将引擎的各个部分移入延伸部分。这样可以实现更好的解耦,删除某些游戏不需要的部件,缩小可执行文件的大小。这还为我们的用户提供了帮助更新扩展程序以及查找/修复错误的可能性。

将来,我们将支持更多的API,例如资源,组件等

我们通过Defold SDK向第三方开发人员公开了扩展api,这使他们可以实现游戏所需的功能。然后,这些扩展可以通过我们的资产门户或Github与其他用户共享。

扩展程序服务器是我们的云构建服务器,开发人员将最终在其中构建自定义引擎(如果他们使用的是本机扩展)。当他们从编辑器(或命令行工具链)中按“ Build and Run”时,此操作将自动完成。服务器支持我们所有平台,这意味着团队的设置过程为零。

Defold正在使用Lua编写游戏逻辑脚本。我们在受支持/允许的平台上支持Lua 5.1以及LuaJIT。本地扩展通常还会注册新的Lua模块供开发人员编写脚本。

我们的资源类型(纹理,子画面,声音文件等)在引擎启动时已注册,具有创建资源或销毁资源的功能。我们对资源使用引用计数。任何系统都可以请求资源需要资源,引用计数将增加。

Defold项目在游戏中的所有资源之间始终具有清晰的依赖关系图。在顶部,我们有game.project,它又引用了其他源文件。这为我们提供了完整的场景图以进行遍历和编译。它还可以确保我们不会在游戏档案中包含多余的内容。

资源系统的主要功能是您可以在编辑器中更改源文件,然后选择将新更改“热重载”到正在运行的游戏实例中。为此,资源系统还具有特殊功能来重新创建资源,因为它可能需要特别注意。

我们的实时更新系统允许将游戏捆绑成发行版时分成两部分。一个是将构建版本上传到应用商店,第二个部分(.zip文件)包含标记为排除的所有资源。

这样可以使游戏的初始下载大小较小,并允许开发人员以后下载其余资源。此系统可在所有平台上运行(允许)。

我们将关卡称为“集合”,每个集合包含一个或多个游戏对象。创建和销毁游戏对象的重量非常轻。加载收藏集后,我们会在池中预分配一定数量的游戏对象。游戏对象的转换最小值是最小的,但也可以包含一个或多个组件。

组件的示例有Collision Object和Sprites。组件通常负责更新实例的属性(例如,Sprite的颜色)。更新组件实例本身,并注册可见的渲染对象。

组件是按类型进行更新的,即它会在for循环中同时更新所有sprites(每个集合)。所有组件类型都按照注册到游戏对象系统的顺序进行更新。

Gui组件是一种特殊类型的组件,它本质上具有自己的子组件集(箱形节点,饼形节点等)。编辑gui文件在编辑器中使用正交视图进行特殊处理,并且还提供了布局切换(土地,肖像等),以便轻松预览。

Defold引擎严重依赖内部系统之间传递消息。它有助于使系统在内部以及脚本游戏逻辑解耦时保持脱钩状态。消息传递系统中的关键组件是URL。如果由“套接字”,“路径”和“片段”组成(例如:level1:/ player#sprite)。在内部,URL会转换为3个散列,以加快查找速度。

在顶层,我们拥有游戏引擎的启动和主循环,尽管其中大多数是相当通用的,但在某些平台上,我们需要特别注意以适合该引擎的方式设置和/或更新引擎平台。

我们还启动了一些特殊的帮助程序服务,例如Web事件探查器和屏幕记录器。

这是一个非常简短的概述,首先要了解引擎中有哪些类型的系统。展望未来,我希望更详细地解释一些领域(例如组件和扩展)

如果您感到好奇,请随时查看源代码