
GDevelop 外部编辑器集成机制解析external 目录、ES Modules 约束与 gdide:// 协议【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop本文聚焦 GDevelop 桌面版newIDE中一个独特而关键的基础设施——newIDE/app/public/external目录。它承载了 GDevelop 内置的第三方编辑器Piskel 像素画编辑器、Jfxr 音效合成器、Yarn 对话树编辑器、Draco 3D 模型压缩解码器并定义了将它们嵌入主编辑器时所必须遵守的两条硬性规则所有文件必须小写命名保证 ES Modules 正常工作与必须使用gdide://自定义协议保证 Electron 能正确伺服 ES 模块。读完本文你将掌握 external 目录的目录结构、编辑器导入脚本的运行机制、ES Modules 与自定义协议背后的工程原因以及第三方编辑器与 GDevelop 主进程之间的消息桥接原理。external 目录的定位内置的第三方编辑器沙箱newIDE/app/public/external/README.md开篇即明确了该目录的定位这个文件夹存放随 GDevelop 一起打包发布的第三方编辑器。它们不是 GDevelop 自己维护的代码而是被借用并嵌入到主编辑器中的外部 HTML5 应用用于在 IDE 内直接完成特定资源的编辑无需离开 GDevelop 切换到外部工具。从当前仓库的目录结构看external 目录下包含四个独立子目录子目录对应的第三方工具在 GDevelop 中的用途newIDE/app/public/external/piskel/Piskel像素画编辑器直接编辑游戏图片资源newIDE/app/public/external/jfxr/Jfxr音效合成器直接编辑/合成音效资源newIDE/app/public/external/yarn/Yarn对话树编辑器创建/编辑 Dialogue Trees对话树newIDE/app/public/external/draco/Draco 3D 压缩解码器提供 wasm 解码能力配合 3D 模型资源使用每个编辑器子目录都遵循几乎相同的布局约定一个*-main.js运行该编辑器的入口代码、一个*-index.html与一个*-electron-index.html分别面向浏览器环境与 Electron 桌面环境、一个*-style.css以及各自的 README。例如 piskel 目录包含piskel-main.js、piskel-index.html、piskel-electron-index.html与piskel-style.cssjfxr 与 yarn 同理。这些*-main.js由 GDevelop 团队编写负责把原始第三方编辑器源码跑起来并接入主编辑器。编辑器源码从哪来import-zipped-editor.js导入机制external 顶层 README 指出这些第三方编辑器通常由import-XXX-editor.js脚本导入位于newIDE/app/scripts目录。搜索仓库可见newIDE/app/scripts下确实存在一系列此类导入脚本import-zipped-editor.js、import-monaco-editor.js、import-libGD.js、import-GDJS-Runtime.js、import-zipped-external-libs.js。其中与 external 目录直接相关的是import-zipped-editor.js每个编辑器子目录的 README 都明确说明Piskel/Jfxr/Yarn 的源码由import-zipped-editor.js脚本下载下载的是第三方编辑器构建产物的原始、未修改源码解压后存放在public/external/editor/editor-editor文件夹中。脚本运行流程阅读 import-zipped-editor.js 源码其执行流程可概括为参数解析node import-zipped-editor.js editor gitRelease expectedFolderHash其中editor是编辑器名如piskelgitRelease是存放 zip 包的 GitHub Release 版本号expectedFolderHash是期望的文件夹 SHA256 校验和。哈希校验通过folder-hash库对public/external/editor/editor-editor目录计算 SHA256与期望值比对。若已存在且校验一致直接跳过下载输出 already existing ... up-to-date。下载解压若目录缺失或校验失败从https://github.com/4ian/GDevelop/releases/download/vgitRelease/editor-editor.zip下载压缩包带 3 次重试、指数退避再用adm-zip解压到public/external/editor目录。事后校验解压完成后重新计算目录哈希。若与期望值不符脚本会输出警告Be careful about potential tampering of the third party editor!防止第三方编辑器被打包时遭到篡改。package.json 中的实际调用newIDE/app/package.json中的import-zipped-external-editors脚本展示了三个编辑器的真实调用参数import-zipped-external-editors: cd scripts node import-zipped-editor.js piskel 5.5.228 b161dc74582e428a6d210cd1b74f052ca4aab301d0d522e0be87bdb4962d0fb7 node import-zipped-editor.js jfxr 5.0.0-beta55 8ac12b557c2ddba958c6f0d3e0c5df8cf3369a65262dcb90cf5c8a7a7d20bdf6 node import-zipped-editor.js yarn 5.0.134 ba8558cad00ec9b18cf3c6fd8647f8c1478ca67c894bca94a152a3740af209cc可见 Piskel、Jfxr、Yarn 分别从5.5.228、5.0.0-beta55、5.0.134三个版本对应的 Release 下载并各自绑定了一串 64 位的 SHA256 目录校验和。而import-resources脚本则把import-zipped-external-editors与import-libGD.js、import-GDJS-Runtime.js、import-monaco-editor.js等串在一起构成一次完整的资源准备流程。这就是开发者在本机执行npm run import-resources后external 目录才会出现完整编辑器的原因。各编辑器的定制说明三个编辑器子目录的 README 还透露了各自的定制深度PiskelGDevelop 使用的是 GDevelopApp/piskelmaster分支的更新版包含大量高级颜色处理功能与面向美术工作流的改进Jfxr用于编辑/合成音效源码是 Jfxr 构建的原始未改动产物Yarn用于创建/编辑 Dialogue Trees与Extensions/DialogueTree扩展配套使用。三者均强调raw, unchanged sources——即内置的是第三方上游构建产物GDevelop 的自有代码*-main.js只负责加载与桥接而非修改第三方源码。两条硬性规则小写文件名与gdide://协议external 顶层 README 的最后一段是该目录工程约束的核心原文明确写道For ES Modules to work, all files must be lower cased. Protocol gdide:// must be used so that Electron can properly serve the ES modules.即为了让 ES Modules 正常工作所有文件必须采用小写命名必须使用gdide://协议Electron 才能正确伺服这些 ES 模块。为什么是小写文件名在 web 服务器环境中URL 路径通常区分大小写而浏览器加载 ES Modules 时会对模块路径做规范化处理大小写不一致极易导致模块解析失败或请求 404。GDevelop 的 external 目录需要同时服务两种宿主浏览器版本web-app通过普通 HTTP 伺服静态文件Electron 桌面版通过自定义协议gdide://伺服文件。为保证同一套第三方编辑器源码尤其是内部大量import ... from ./xxx.js的相对导入在两种宿主下都能被 ES Modules 加载器命中仓库规定该目录下所有文件一律小写命名。这也解释了为何 external 目录内出现的都是piskel-main.js、jfxr-electron-index.html这类全小写文件名。为什么是gdide://协议Electron 的file://协议在加载本地 HTML 及其 ES Modules 时存在诸多限制CORS、模块加载路径等因此 GDevelop 注册了一个自定义的gdide://协议处理器把协议请求映射到public/external下的实际文件。这样第三方编辑器页面可以通过gdide://开头的 URL 被加载Electron 侧才能以符合 ES Modules 规范的方式伺服文件——这正是 README 中 Protocol gdide:// must be used so that Electron can properly serve the ES modules 的工程含义。从目录结构可推断*-electron-index.html正是面向该协议/Electron 宿主的入口而*-index.html则服务于浏览器宿主。第三方编辑器与主编辑器之间的桥接external 目录下的第三方编辑器并不是孤立运行的 iframe 页面它们需要与 GDevelop 主编辑器交换数据例如把画好的图、生成的音效、写好的对话树交回给项目资源。这一桥接层由两部分构成1. 编辑器侧的工具脚本external/utilsnewIDE/app/public/external/utils/目录提供了三个共享工具parent-editor-interface.js封装了编辑器与父窗口/主进程通信的统一接口。其核心是双通道自适应在 Electron 环境下通过require(electron)拿到ipcRenderer与electron/remote的当前窗口用ipcRenderer.send(id, payload)发送消息、ipcRenderer.on(id, callback)接收消息在浏览器环境下退化为window.opener.postMessage(...)与window.addEventListener(message, ...)同时提供setTitle、closeWindow等窗口控制方法。这套设计让同一份编辑器代码在桌面端与 Web 端都能与主编辑器通信。external-editor-header.js创建编辑器顶部的工具栏提供资源名的文本输入框、Overwrite覆盖已有资源/ New新建资源下拉选择以及 Save/Cancel 按钮是第三方编辑器保存流程的 UI 层。external-editor-header.css对应工具栏样式base64.js则提供 base64 编解码辅助用于把二进制资源编码后在窗口间传递。2. 主编辑器侧的桥接文件三个编辑器 README 不约而同地指向了同一组桥接文件SeeLocalExternalEditorWindow.js,LocalResourceExternalEditors.jsandBrowserResourceExternalEditors.jsfiles for the bridge that opens the Window and passes data from GDevelop to Piskel/Jfxr/Yarn.在仓库中newIDE/app/src/LocalApp.js与newIDE/app/src/BrowserApp.js都引用了LocalResourceExternalEditors/BrowserResourceExternalEditors相关模块且存在配套测试 LocalResourceExternalEditors.spec.js。从命名与 README 描述可以推断这套桥接的分工LocalExternalEditorWindow本地/桌面端负责在 Electron 中打开承载第三方编辑器的新窗口并把项目数据从 GDevelop 传入编辑器LocalResourceExternalEditors桌面端资源与外部编辑器之间的适配层负责把用 Piskel 编辑这张图/用 Jfxr 编辑这个音效/用 Yarn 编辑这段对话树的用户操作路由到对应编辑器窗口BrowserResourceExternalEditors浏览器端的对应实现通常以弹窗window.open形式承载编辑器。也就是说Piskel/Jfxr/Yarn 三个编辑器的接入逻辑高度同构打开窗口 → 通过parent-editor-interface.js的postMessage/ipcRenderer通道传数据 → 编辑器内编辑 → 用户点击 Save → 数据回传主编辑器 → 资源落盘。external 目录中的*-main.js正是这一流程在编辑器侧的编排者。小结一条可复用的第三方编辑器接入范式从 external 目录整体设计可以看出GDevelop 为在 IDE 内嵌入第三方 HTML5 编辑器沉淀出了一套完整范式存放第三方构建产物放在newIDE/app/public/external/name/name-editor/遵循全小写命名导入通过newIDE/app/scripts/import-zipped-editor.js按版本从 GitHub Release 下载并校验 SHA256调用参数固化在newIDE/app/package.json的import-zipped-external-editors脚本中伺服浏览器用普通静态文件服务Electron 用gdide://自定义协议服务 ES Modules桥接借助external/utils/parent-editor-interface.js的统一消息封装配合LocalExternalEditorWindow/LocalResourceExternalEditors/BrowserResourceExternalEditors完成窗口打开与数据双向传递。理解这套机制后无论是排查external 编辑器加载失败优先检查文件夹是否小写、gdide://协议是否正确注册、编辑器 zip 版本与哈希是否匹配还是想为 GDevelop 接入新的第三方编辑器都可以沿着上述四个环节快速定位问题所在。【免费下载链接】GDevelop Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.项目地址: https://gitcode.com/GitHub_Trending/gd/GDevelop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考