ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GDevelop 架构深度解析:Core、GDJS、Extensions、GDevelop.js 与 newIDE 五大模块的设计与协作

GDevelop 架构深度解析:Core、GDJS、Extensions、GDevelop.js 与 newIDE 五大模块的设计与协作 GDevelop 架构深度解析Core、GDJS、Extensions、GDevelop.js 与 newIDE 五大模块的设计与协作【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop导读GDevelop 是一个开源、跨平台的 2D/3D/多人游戏引擎其代码仓库的顶层目录结构本身就是一套清晰的架构宣言Core负责描述与操作游戏工程结构GDJS是纯 TypeScript 编写的运行时游戏引擎Extensions提供可插拔的对象、行为与事件扩展GDevelop.js通过 Emscripten/WebIDL 把 C 世界桥接到浏览器newIDE则是基于 React 的图形化编辑器。本文基于 Core/GDevelop-Architecture-Overview.md 展开结合仓库内真实源码与测试帮助你理解IDE 部分与Runtime 部分的分界、事件如何被转译为真实代码、三个 Extensions 文件夹为何并存以及 GDevelop.js 桥接层的工作方式——读完即可在源码树中快速定位任意功能模块。顶层目录五张名片一条主线GDevelop 的架构围绕一个核心思想展开编辑器IDE与游戏引擎Runtime解耦编辑器使用所有底层库来读写、校验并导出游戏而导出的游戏只依赖运行时引擎。仓库根目录下五个主要目录的分工如下目录说明CoreGDevelop 核心库包含实现 IDE 与处理 GDevelop 游戏所需的通用工具全部为 C 实现。GDJS游戏引擎用 TypeScript 编写基于 PixiJSWebGL驱动所有 GDevelop 游戏运行。GDevelop.jsCore、GDJS与Extensions到 JavaScriptWebAssembly的绑定层供 IDE 使用。newIDE游戏编辑器用 JavaScript React Electron PixiJS 编写另有 web 版本。Extensions游戏引擎的扩展提供对象、行为、事件与各种新特性。主线关系是newIDE编辑器通过GDevelop.js桥接层调用Core的 C 类来操作工程结构通过GDJS/GDJS的 C 声明获得导出与代码生成能力最终产出包含GDJS/Runtime代码的游戏包。先厘清两个概念Runtime 与 IDE文档用两个词区分整个仓库中的所有代码IDEIntegrated Development Environment指编辑器本身。浏览Core或GDJS的子目录时你会看到名为IDE的文件夹里面的类与工具只对编辑器有用并非描述游戏结构的必需品。例如 Core/GDCore/IDE 中存放的就是编辑器侧的操作工具。Runtime指游戏运行期间使用的类、工具与源码也就是常说的游戏引擎。GDJS子目录下的Runtime文件夹就是 GDevelop 的游戏引擎本体全部由 TypeScript 编写。扩展Extensions同样遵循这一区分大多数扩展都包含两部分——一个用于IDE的声明文件JsExtension.js以及一个或多个实现游戏内功能的Runtime文件例如 Runtime Object、Runtime Behavior或由动作/条件调用的工具函数。用gd::Variable理解两层世界的隔离文档用变量类作为最佳例证GDevelop 允许开发者在游戏中创建和操作变量但这一概念在仓库中对应两个互不相干的实现编辑器侧的gd::Variable属于游戏工程结构的一部分定义在 Core/GDCore/Project/Variable.h。编辑器界面中展示的、保存到工程文件JSON里的就是这个类。游戏引擎侧的gdjs.Variable定义在 GDJS/Runtime/variable.ts是游戏运行时真正使用的 JavaScript 类。两个类的关系近乎失联编辑器gd::Variable对引擎类gdjs.Variable一无所知引擎类除了知道如何读取默认变量写入的 JSON 格式之外对gd::Variable也几乎一无所知。从variable.ts源码可以看到gdjs.Variable的构造逻辑正是从childDataJSON 数据递归构建子变量树。文档还指出一个命名上的小历史遗留gdjs.Variable其实应该叫gdjs.RuntimeVariable与gdjs.RuntimeObject以及引擎中绝大多数类的命名保持一致。这种刻意隔离正是 GDevelop 架构的精髓编辑器保存的工程结构只是设计图游戏运行时则是完全独立的执行世界两者通过序列化JSON单向沟通。Core 内部游戏结构的描述与操作Core即GDCore文件夹本质上包含描述和操作游戏结构内部称为Project所需的全部内容事件、场景Layout、对象、行为、变量等均以 C 类实现于 Core/GDCore/Project 目录。从目录清单可以直观看到它的覆盖面工程与场景Project.h、Layout.h、LayersContainer.h、ExternalLayout.h、ExternalEvents.h对象与行为Object.h、Behavior.h、BehaviorsContainer.h、CustomBehavior.h、EventsBasedObject.h、EventsFunctionsExtension.h变量Variable.h、VariablesContainer.h初始实例与资源InitialInstance.h、InitialInstancesContainer.h、ResourcesContainer.h。除了数据模型Core还提供操作 Project 的工具。Core/GDCore/IDE 目录包含允许对游戏结构执行复杂操作的 C 类其中最典型的是 WholeProjectRefactorer——一个非常强大的工具用于在项目中重命名所有对象、在对象被删除后自动更新事件以及执行各种全局性的工程重构。该目录下还有其他工具函数例如操作项目资源的系列类ResourcesMergingHelper、ResourcesRenamer、ArbitraryResourceWorker等均可在 GDevelop.js/Bindings/Wrapper.cpp 的 include 清单中看到以及在事件中搜索的工具EventsIdentifiersFinder、EventsVariablesFinder、EventsRefactorer等。GDJS 内部为什么这里也有 C 文件GDJS目录下同时存在两个世界GDJS/Runtime真正的游戏引擎全部用 TypeScript 编写是游戏运行期间被执行的代码。GDJS/GDJSGDJS 的 IDE 部分即用 C 编写的、向编辑器描述各种能力的类例如导出如何完成导出流程相关的声明默认扩展有哪些该目录下有SpriteExtension、AudioExtension、CommonInstructionsExtension、KeyboardExtension、MouseExtension、TimeExtension、VariablesExtension、SceneExtension等 19 组内置扩展负责把编辑器中的动作/条件/表达式映射到具体的 TypeScript 或 C 函数如何从事件生成 JS 代码该目录包含EventsCodeGenerator、LayoutCodeGenerator、ObjectCodeGenerator、BehaviorCodeGenerator、EventsFunctionsExtensionCodeGenerator等核心代码生成器。事件系统从空壳到真实代码事件是一块几乎为空的容器在 GDevelop 中一个事件event默认情况下几乎什么都没有。用传统编程语言类比事件相当于一个作用域/代码块如 C 系语言里的{ 一些代码 }。内置事件默认在 GDevelop Core 中定义。从目录可见既有StandardEvent标准事件含条件与动作也有ForEachEvent、WhileEvent、RepeatEvent、GroupEvent、CommentEvent、ElseEvent、LinkEvent、AsyncEvent等控制流事件。其中StandardEvent拥有条件conditions与动作actions而条件和动作本质上都是gd::Instruction的列表。gd::Instruction一个函数调用一个gd::Instruction只是一个类型动作或条件的名称加若干参数。可以把它想象成编程语言中的函数调用add(2, 3)就是调用名为 add 的函数并传入参数 2 和 3。条件特殊之处在于它是返回 true 或 false 的函数并且可能被用来对对象进行过滤——从而影响后续条件和动作拾取picking到的对象集合。为什么游戏运行时看不到任何 RuntimeEvent因为它们已经不存在了。事件会被翻译文档中也称转译或生成即 transpiled / generated成真正的编程语言代码这个过程叫Code Generation代码生成对 TypeScript 游戏引擎而言发生在 GDJS/GDJS/Events/CodeGeneration。也就是说编辑器中可视化编排的事件在导出时被EventsCodeGenerator等 C 类直接转译为GDJS/Runtime中可执行的 JavaScript/TypeScript 逻辑运行时不再保留事件对象本身。这也是 GDevelop 事件系统性能与运行时纯净度的根源。三个 Extensions 文件夹为什么会有三个GDevelop 编辑器和游戏引擎的设计理念是引擎本身保持精简几乎不内置任何功能通过模组 / 插件 / 模块来按需添加能力GDevelop 称之为Extensions扩展。仓库中有三个 Extensions 相关目录职责各不相同目录职责Core/GDCore/Extensions默认内置扩展的声明任何游戏都可用且必须存在。虽然名为 Extensions但本质相当于编程语言中的标准库Standard Library。GDJS/GDJS/Extensions复用上述声明并追加自己的声明。主要工作是为每个动作、条件或表达式指定要调用的函数名可以是 TypeScript 函数或 C 函数。Extensions真正的模组 / 插件目录——非必需的扩展。它们不属于 GDCore独立运作。文档特别说明理论上所有扩展都可以搬到Extensions/但实践中保留一组内置扩展提供基础能力更务实。GDevelop.js把 C 世界桥接给 JavaScript 编辑器GDevelop.js的一切都服务于一个目标为 IDE 建立 C 与 JavaScript 之间的桥让编辑器完全用 JavaScript 编写并能在浏览器中运行即newIDE。其技术要点Emscripten 编译 C与编译原生二进制不同Emscripten 产出的是能在浏览器中运行的文件本质是 JavaScript WebAssembly。Bindings.idl是核心文件GDevelop.js/Bindings/Bindings.idl 描述了 C 中需要暴露给 JavaScript 的每一样东西。需要强调这些暴露只服务于编辑器——游戏运行时Runtime中这一切都不存在。其余文件是桥接代码负责 JS ↔ C 的双向翻译。这需要理解 Emscripten 生成的名为 WebIDL 的桥机制。除非你想把某个 C 类暴露给编辑器、且仅写Bindings.idl接口还不够否则通常不需要深入这些文件——90% 的情况下在Bindings.idl中读写一个类的声明即可。GDevelop.js 的底层细节所有需要参与编译的 C 文件都被集中引入到 GDevelop.js/Bindings/Wrapper.cpp 这个巨大的头文件清单中该文件共 984 行前 90 行即包含GDCore/Events/Builtin/*全部内置事件、GDCore/IDE/Events/*全部事件工具、GDCore/Project/*全部工程模型以及GDCore/Extensions/Metadata/*元数据类。C 编译由 CMake 构建系统驱动依据 GDevelop.js/CMakeLists.txt 决定编译内容。文档作者也坦言理想情况下应有自动化手段完成这一过程那样 GDevelop.js 文件夹甚至都不需要存在。常见疑问为什么这么多 C 与 JavaScript/TypeScript为什么用这么多 CGDevelop 最初就是用 C 编写的。C 初学起来有些吓人但它几乎可以在现存任何机器上移植配合最新的 C 特性可以写出相当高效、安全且可读的代码。Core、GDJS 的 IDE 部分以及扩展的声明层都依赖它。为什么又用这么多 JavaScript/TypeScriptJavaScript配合最新语言提案能力很强、编写快速且有类型保障现代浏览器 JIT 特性使性能不断提升用于 GDevelop IDE 的前端框架 React 支持非常快速、模块化的界面开发Web 是跨平台以及跨形态应用无可比拟的发布目标。更宏观地看随着 WebGL 与 WebAssembly 的兴起Web 也是游戏发布的绝佳目标——同时 GDevelop 也保持模块化以便未来为导出游戏适配更新的平台。总结一张地图定位整个仓库把全文浓缩成一张寻路地图想看工程结构模型去 Core/GDCore/Project想看编辑器侧的重构/搜索工具去 Core/GDCore/IDE想看事件如何变成代码去 GDJS/GDJS/Events/CodeGeneration想看游戏真正跑起来的逻辑去 GDJS/Runtime想看可插拔新特性怎么声明去 Extensions/ExampleJsExtension想看C 如何暴露给 JS 编辑器去 GDevelop.js/Bindings/Bindings.idl。理解了 IDE 部分与 Runtime 部分这条分界线GDevelop 的每一行代码都会各归其位。【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表