Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

自定义平台的移植

自定义 C++ 模块 (在 C++ 中编写自定义模块)类似,Godot 的多平台架构在设计上就允许开发者在不修改任何现有源码的情况下,直接创建新的平台移植版。

FRT 就是一个不依赖引擎官方源码、独立分发的自定义平台移植版实例,它的目标平台是各类单板计算机。需要注意的是,目前的 FRT 移植版是基于 Godot 3.x 版本的;因此,它并没有使用 Godot 4 中全新的 DisplayServer (显示服务器)抽象层。

创建自定义平台移植可能有以下原因:

  • 你想把你的游戏移植到游戏主机上(也可以参考 Godot 官网关于主机支持的页面),并且希望由自己来编写底层的平台适配代码。这是一条漫长且充满艰辛的道路,因为它需要你与各大主机厂商签署保密协议(NDA),不过这样做的好处是,你能对整个主机移植的流程拥有完全的控制权。

  • 你想把 Godot 移植到一个目前尚未支持的、比较冷门的平台上。

如果你有关于创建自定义平台移植版本的问题,欢迎随时在 Godot 贡献者聊天室t#platforms 频道提问。

备注

Godot 是一个现代引擎,自然也有着现代的配置要求。哪怕你只打算在目标平台上运行简单的 2D 项目,它依然需要消耗一定的内存,这导致在绝大多数复古游戏机上运行它都是不切实际的。作为参考,在 Godot 4 中,一个里面什么都没有的空白项目,在 Linux 系统下运行大约就需要占用 100 MB 的内存(如果是在无界面模式下运行,也需要 50 MB)。

如果你想在内存极度受限的平台上运行 Godot,可以尝试旧版本的 Godot,它们的内存占用要求会更低。移植过程大致相同,唯一的区别在于:旧版本中的 DisplayServer 还没有从 OS 单例类中拆分出来。

官方的平台移植

创建自定义平台移植时,可以使用官方的平台移植作为参考:

虽然平台相关的代码通常是独立存放(自包含)的,但也有例外。比如,那些被多个平台共用的音频驱动,以及渲染驱动,它们都被放在了 Godot 源码的 drivers/ folder 里。

创建自定义平台移植

创建自定义平台移植是一项繁重的工作,同时需要熟悉对应平台的 SDK。工作量因所需的功能而异:

平台移植的必要功能

平台移植至少需要实现 OS 单例中的方法才能够进行构建,用于无头操作。平台文件夹中还需要存在一张名为 logo.svg 的矢量图(32×32)。“导出”对话框中为该平台定义的导出预设就会显示这个图标。

示例实现请参考 Linux/*BSD 平台。另见 OS 单例头文件

备注

如果你的目标平台是类 UNIX 平台,请考虑继承 OS_Unix 类,这样就能够自动完成大量工作。

如果你的平台不是类 UNIX 系统,你可以参考 Windows port 的代码。

detect.py 文件

必须在平台的文件夹内创建一个 detect.py 文件,并实现其中的所有方法。SCons 需要依靠这个文件,才能把你的平台识别为一个有效的编译选项。具体可以参考 Linux/BSD 平台的 detect.py file 作为示例。

detect.py 应实现如下所有方法:

  • is_active():可以用来临时禁用某个平台的构建。一般都应该返回 True

  • get_name():返回平台的用户可见名称字符串。

  • can_build():如果宿主系统能够构建目标平台则返回 True,否则返回 False。请勿在此处进行耗时的检查,用户请求平台列表时会查询该函数。大量的依赖项检查请使用 configure()

  • get_opts():返回用户能够为该平台定义的 Scons 构建选项列表。

  • get_flags():返回该平台覆盖的 Scons 标识列表。

  • configure():执行构建配置,例如根据所选的 SCons 选项调整编译器选项。

平台移植的可选功能

实践中,如果你想要在屏幕和手持输入设备上看到画面,那么需要的就不仅仅是无头操作。大多数游戏可能还会需要音频输出。

本列表中的部分链接以 Linux/*BSD 平台的实现作为参考。

  • 一个或多个 DisplayServer(显示服务器),并且需要实现其中的窗口化相关方法。DisplayServer 还涵盖了鼠标支持、触摸屏支持以及绘图板驱动(用于手写笔输入)等功能。具体可以参考 DisplayServer 单例类的头文件

    • 对于不支持完整窗口系统的平台(或者如果你正在做的移植版本不需要考虑这些),大部分窗口相关函数都可以保持未实现的状态(留空)。这些函数只需要检查窗口 ID 是否为 MAIN_WINDOW_ID 即可,而像调整窗口大小这类特定操作,可以绑定到该平台的屏幕分辨率功能上(如果适用的话)。任何试图创建或操作其他窗口 ID 的行为都可以直接拒绝。

  • 如果目标平台支持上述图形 API: 则需要提供 VulkanDirect3D 12OpenGL 3.3 或 OpenGL ES 3.0 的渲染上下文。

  • 用于 键盘游戏手柄(控制器) 的输入处理器。

  • 一个或多个 音频驱动。音频驱动可以放在 platform/ 文件夹里(Android 和 Web 平台就是这么做的),或者,如果这个音频驱动可能会被多个平台共用,那就把它放在 drivers/ 文件夹里。具体可以参考 AudioServer 单例类的头文件

  • Crash handler,用于在游戏崩溃时打印出崩溃回溯信息(backtraces)。这能让那些不方便直接查看日志文件的平台,排查问题变得更加容易。

  • 文本转语音 (Text-to-speech) 驱动 (用于无障碍辅助功能)。

  • 导出处理器(Export handler) (用于从编辑器中进行导出,包括 一键部署)一键部署)。如果你只打算从编辑器导出一个 PCK 资源包,然后通过将导出模板的可执行文件重命名为与 PCK 文件同名来直接运行它,那么就不需要配置导出处理器。具体可以参考 EditorExportPlatform header 。如果目标平台实现了 一键部署 (一键部署)功能,那么平台的文件夹中应该包含一个 run_icon.svg (16×16 尺寸)图标。当为目标平台设置好一键部署后,这个图标会显示在编辑器的顶部。

如果目标平台不支持运行 Vulkan、Direct3D 12、OpenGL 3.3 或 OpenGL ES 3.0,那你还有两个选择:

  • 在运行时使用一个库,将 Vulkan 或 OpenGL 的调用指令转换为其他的图形 API。例如,在 macOS 上使用的`MoltenVK <https://moltengl.com/moltenvk/>`__ ,就是用来在运行时将 Vulkan 指令转换为 Metal 指令的。

  • 从零开始创建一个新的渲染器。这是一项浩大的工程,特别是如果你还希望它能支持带有高级特性的 2D 和 3D 渲染的话。

分发自定义平台移植

危险

分发自定义平台移植之前,请先确定你有权利分发所有被链接的代码。主机平台的 SDK 通常存在相关的保密协议,禁止向公众进行二次分发。

平台移植的设计尽量做到了自包含。大多数代码都在 platform/ 下的某个文件夹中。这种设计与 自定义 C++ 模块 类似,能够允许将平台文件夹 git clone 至 Godot 仓库副本的 platform/ 文件夹中,后续执行 scons platform=<name> 即可,使得构建过程流水线化。除非有第三方平台特定的依赖项需要安装,否则构建时不需要其他步骤。

不过,当需要一个自定义的渲染驱动时,就必须在 drivers/ 目录下新增一个文件夹。在这种情况下,该平台的移植版本既可以作为一个 Godot 仓库的分支(fork)来分发,也可以作为一组文件夹的集合,直接添加到一个 Godot Git 仓库的克隆版本中。