From f658307ac7824e0c99e79444dfc3fc4309562939 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 27 Oct 2022 23:29:35 +0200 Subject: [PATCH] Add a page on creating custom platform ports --- about/list_of_features.rst | 6 +- .../introduction_to_the_buildsystem.rst | 2 +- .../binding_to_external_libraries.rst | 2 +- .../core_and_modules/custom_audiostreams.rst | 2 +- .../core_and_modules/custom_godot_servers.rst | 2 +- .../custom_modules_in_cpp.rst | 2 +- .../custom_platform_ports.rst | 190 ++++++++++++++++++ .../custom_resource_format_loaders.rst | 2 +- .../development/core_and_modules/index.rst | 1 + .../introduction_to_editor_development.rst | 2 +- tutorials/performance/cpu_optimization.rst | 2 +- .../gdextension/what_is_gdextension.rst | 4 +- 12 files changed, 204 insertions(+), 13 deletions(-) create mode 100644 contributing/development/core_and_modules/custom_platform_ports.rst diff --git a/about/list_of_features.rst b/about/list_of_features.rst index 7b3083412..0045664ca 100644 --- a/about/list_of_features.rst +++ b/about/list_of_features.rst @@ -34,8 +34,8 @@ Platforms - iOS 11.0 and later. - :ref:`Consoles `. -Godot aims to be as platform-independent as possible and can be ported to new -platforms with relative ease. +Godot aims to be as platform-independent as possible and can be +:ref:`ported to new platforms ` with relative ease. Editor ------ @@ -718,7 +718,7 @@ Miscellaneous - Print colored text to standard output on all platforms using :ref:`print_rich `. -- Support for :ref:`C++ modules ` statically linked +- Support for :ref:`C++ modules ` statically linked into the engine binary. - Engine and editor written in C++17. diff --git a/contributing/development/compiling/introduction_to_the_buildsystem.rst b/contributing/development/compiling/introduction_to_the_buildsystem.rst index ce5fe23d3..e46446e0d 100644 --- a/contributing/development/compiling/introduction_to_the_buildsystem.rst +++ b/contributing/development/compiling/introduction_to_the_buildsystem.rst @@ -208,7 +208,7 @@ directory paths containing such modules: .. seealso:: - :ref:`doc_custom_modules_in_c++` + :ref:`doc_custom_modules_in_cpp` Cleaning generated files ------------------------ diff --git a/contributing/development/core_and_modules/binding_to_external_libraries.rst b/contributing/development/core_and_modules/binding_to_external_libraries.rst index ca8db1fbf..dba80931d 100644 --- a/contributing/development/core_and_modules/binding_to_external_libraries.rst +++ b/contributing/development/core_and_modules/binding_to_external_libraries.rst @@ -6,7 +6,7 @@ Binding to external libraries Modules ------- -The Summator example in :ref:`doc_custom_modules_in_c++` is great for small, +The Summator example in :ref:`doc_custom_modules_in_cpp` is great for small, custom modules, but what if you want to use a larger, external library? Let's look at an example using `Festival `_, a speech synthesis (text-to-speech) library written in C++. diff --git a/contributing/development/core_and_modules/custom_audiostreams.rst b/contributing/development/core_and_modules/custom_audiostreams.rst index 251929b12..c1c07beb9 100644 --- a/contributing/development/core_and_modules/custom_audiostreams.rst +++ b/contributing/development/core_and_modules/custom_audiostreams.rst @@ -17,7 +17,7 @@ its own internal custom AudioStreamPlayback which translates AudioStream into PCM data. This guide assumes the reader knows how to create C++ modules. If not, refer to this guide -:ref:`doc_custom_modules_in_c++`. +:ref:`doc_custom_modules_in_cpp`. References: ~~~~~~~~~~~ diff --git a/contributing/development/core_and_modules/custom_godot_servers.rst b/contributing/development/core_and_modules/custom_godot_servers.rst index 5315407a4..2528b2c02 100644 --- a/contributing/development/core_and_modules/custom_godot_servers.rst +++ b/contributing/development/core_and_modules/custom_godot_servers.rst @@ -13,7 +13,7 @@ engine and other modules. In addition, the server claims ownership for its RID allocations. This guide assumes the reader knows how to create C++ modules and Godot -data types. If not, refer to :ref:`doc_custom_modules_in_c++`. +data types. If not, refer to :ref:`doc_custom_modules_in_cpp`. References ~~~~~~~~~~~ diff --git a/contributing/development/core_and_modules/custom_modules_in_cpp.rst b/contributing/development/core_and_modules/custom_modules_in_cpp.rst index b9ccc0df5..bce51bee4 100644 --- a/contributing/development/core_and_modules/custom_modules_in_cpp.rst +++ b/contributing/development/core_and_modules/custom_modules_in_cpp.rst @@ -1,4 +1,4 @@ -.. _doc_custom_modules_in_c++: +.. _doc_custom_modules_in_cpp: Custom modules in C++ ===================== diff --git a/contributing/development/core_and_modules/custom_platform_ports.rst b/contributing/development/core_and_modules/custom_platform_ports.rst new file mode 100644 index 000000000..737d21a4c --- /dev/null +++ b/contributing/development/core_and_modules/custom_platform_ports.rst @@ -0,0 +1,190 @@ +.. _doc_custom_platform_ports: + +Custom platform ports +===================== + +Similar to :ref:`doc_custom_modules_in_cpp`, Godot's multi-platform architecture +is designed in a way that allows creating platform ports without modifying any +existing source code. + +An example of a custom platform port distributed independently from the engine +is `FRT `__, which targets single-board +computers. Note that this platform port currently targets Godot 3.x; therefore, +it does not use the :ref:`class_DisplayServer` abstraction that is new in Godot 4. + +Some reasons to create custom platform ports might be: + +- You want to :ref:`port your game to consoles `, but wish to + write the platform layer yourself. This is a long and arduous process, as it + requires signing NDAs with console manufacturers, but it allows you to have + full control over the console porting process. +- You want to port Godot to an exotic platform that isn't currently supported. + +If you have questions about creating a custom platform port, feel free to ask in +the ``#platforms`` channel of the +`Godot Contributors Chat `__. + +.. note:: + + Godot is a modern engine with modern requirements. Even if you only + intend to run simple 2D projects on the target platform, it still requires + an amount of memory that makes it unviable to run on most retro consoles. + For reference, in Godot 4, an empty project with nothing visible requires + about 100 MB of RAM to run on Linux (50 MB in headless mode). + + If you want to run Godot on heavily memory-constrained platforms, older + Godot versions have lower memory requirements. The porting process is + similar, with the exception of :ref:`class_DisplayServer` not being split + from the :ref:`class_OS` singleton. + +Official platform ports +----------------------- + +The official platform ports can be used as a reference when creating a custom platform port: + +- `Windows `__ +- `macOS `__ +- `Linux/\*BSD `__ +- `Android `__ +- `iOS `__ +- `UWP `__ *(not currently working)* +- `Web `__ + +While platform code is usually self-contained, there are exceptions to this +rule. For instance, audio drivers that are shared across several platforms and +rendering backends are located in the +`drivers/ folder `__ +of the Godot source code. + +Creating a custom platform port +------------------------------- + +Creating a custom platform port is a large undertaking which requires prior +knowledge of the platform's SDKs. Depending on what features you need, the +amount of work needed varies: + +Required features of a platform port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +At the very least, a platform port must have methods from the :ref:`class_OS` +singleton implemented to be buildable and usable for headless operation. +A ``logo.png`` (32×32) image must also be present within the platform folder. +This logo is displayed in the Export dialog for each export preset targeting +the platform in question. + +See `this implementation `__ +for the Linux/\*BSD platform as an example. See also the +`OS singleton header `__ +for reference. + +.. note:: + + If your target platform is UNIX-like, consider inheriting from the ``OS_Unix`` + class to get much of the work done automatically. + + If the platform is not UNIX-like, you might use the + `Windows port ` + as a reference. + +**detect.py file** + +A ``detect.py`` file must be created within the platform's folder with all +methods implemented. This file is required for SCons to detect the platform as a +valid option for compiling. See the +`detect.py file `__ +for the Linux/\*BSD platform as an example. + +All methods should be implemented within ``detect.py`` as follows: + +- ``is_active()``: Can be used to temporarily disable building for a platform. + This should generally always return ``True``. +- ``get_name()``: Returns the platform's user-visible name as a string. +- ``can_build()``: Return ``True`` if the host system is able to build for the + target platform, ``False`` otherwise. Do not put slow checks here, as this is + queried when the list of platforms is requested by the user. Use + ``configure()`` for extensive dependency checks instead. +- ``get_opts()``: Returns the list of SCons build options that can be defined by + the user for this platform. +- ``get_flags()``: Returns the list of overridden SCons flags for this platform. +- ``configure()``: Perform build configuration, such as selecting compiler + options depending on SCons options chosen. + +Optional features of a platform port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In practice, headless operation doesn't suffice if you want to see anything on +screen and handle input devices. You may also want audio output for most +games. + +*Some links on this list point to the Linux/\*BSD platform implementation as a reference.* + +- One or more `DisplayServers `__, + with the windowing methods implemented. DisplayServer also covers features such + as mouse support, touchscreen support and tablet driver (for pen input). + See the + `DisplayServer singleton header `__ + for reference. + + - For platforms not featuring full windowing support (or if it's not relevant + for the port you are making), most windowing functions can be left mostly + unimplemented. These functions can be made to only check if the window ID is + ``MAIN_WINDOW_ID`` and specific operations like resizing may be tied to the + platform's screen resolution feature (if relevant). Any attempt to create + or manipulate other window IDs can be rejected. +- *If the target platform supports the graphics APIs in question:* Rendering + context for `Vulkan `__, + `OpenGL 3.3 or OpenGL ES 3.0 `__. +- Input handlers for `keyboard `__ + and `controller `__. +- One or more `audio drivers `__. + The audio driver can be located in the ``platform/`` folder (this is done for + the Android and Web platforms), or in the ``drivers/`` folder if multiple + platforms may be using this audio driver. See the + `AudioServer singleton header `__ + for reference. +- `Crash handler `__, + for printing crash backtraces when the game crashes. This allows for easier + troubleshooting on platforms where logs aren't readily accessible. +- `Text-to-speech driver `__ + (for accessibility). +- `Export handler `__ + (for exporting from the editor, including :ref:`doc_one-click_deploy`). + Not required if you intend to export only a PCK from the editor, then run the + export template binary directly by renaming it to match the PCK file. See the + `EditorExportPlatform header `__ + for reference. + ``run_icon.png`` (16×16) should be present within the platform folder if + :ref:`doc_one-click_deploy` is implemented for the target platform. This icon + is displayed at the top of the editor when one-click deploy is set up for the + target platform. + +If the target platform doesn't support running Vulkan, OpenGL 3.3 or OpenGL ES 3.0, +you have two options: + +- Use a library at run-time to translate Vulkan or OpenGL calls to another graphics API. + For example, `MoltenVK `__ is used on macOS + to translate Vulkan to Metal at run-time. +- Create a new renderer from scratch. This is a large undertaking, especially if + you want to support both 2D and 3D rendering with advanced features. + +Distributing a custom platform port +----------------------------------- + +.. warning:: + + Before distributing a custom platform port, make sure you're allowed to + distribute all the code that is being linked against. Console SDKs are + typically under NDAs which prevent redistribution to the public. + +Platform ports are designed to be as self-contained as possible. Most of the +code can be kept within a single folder located in ``platform/``. Like +:ref:`doc_custom_modules_in_cpp`, this allows for streamlining the build process +by making it possible to ``git clone`` a platform folder within a Godot repository +clone's ``platform/`` folder, then run ``scons platform=``. No other steps are +necessary for building, unless third-party platform-specific dependencies need +to be installed first. + +However, when a custom rendering backend is needed, another folder must be added +in ``drivers/``. In this case, the platform port can be distributed as a fork of +the Godot repository, or as a collection of several folders that can be added +over a Godot Git repository clone. diff --git a/contributing/development/core_and_modules/custom_resource_format_loaders.rst b/contributing/development/core_and_modules/custom_resource_format_loaders.rst index 8ff0bab1c..15100d828 100644 --- a/contributing/development/core_and_modules/custom_resource_format_loaders.rst +++ b/contributing/development/core_and_modules/custom_resource_format_loaders.rst @@ -12,7 +12,7 @@ path again, the previous loaded Resource will be referenced. Naturally, loaded resources must be stateless. This guide assumes the reader knows how to create C++ modules and Godot -data types. If not, refer to this guide: :ref:`doc_custom_modules_in_c++` +data types. If not, refer to this guide: :ref:`doc_custom_modules_in_cpp` References ~~~~~~~~~~ diff --git a/contributing/development/core_and_modules/index.rst b/contributing/development/core_and_modules/index.rst index 8c5036e25..1c03daaca 100644 --- a/contributing/development/core_and_modules/index.rst +++ b/contributing/development/core_and_modules/index.rst @@ -34,4 +34,5 @@ This section covers what you can do by modifying Godot's C++ source code. custom_godot_servers custom_resource_format_loaders custom_audiostreams + custom_platform_ports unit_testing diff --git a/contributing/development/editor/introduction_to_editor_development.rst b/contributing/development/editor/introduction_to_editor_development.rst index 892bc4896..56adb08e7 100644 --- a/contributing/development/editor/introduction_to_editor_development.rst +++ b/contributing/development/editor/introduction_to_editor_development.rst @@ -37,7 +37,7 @@ The editor's code is fully self-contained in the of the Godot source repository. Some editor functionality is also implemented via -:ref:`modules `. Some of these are only enabled in +:ref:`modules `. Some of these are only enabled in editor builds to decrease the binary size of export templates. See the `modules/ `__ folder in the Godot source repository. diff --git a/tutorials/performance/cpu_optimization.rst b/tutorials/performance/cpu_optimization.rst index e48279e41..e19ce130c 100644 --- a/tutorials/performance/cpu_optimization.rst +++ b/tutorials/performance/cpu_optimization.rst @@ -201,7 +201,7 @@ Godot is written in C++. Using C++ will usually result in the fastest code. However, on a practical level, it is the most difficult to deploy to end users' machines on different platforms. Options for using C++ include GDExtensions and -:ref:`custom modules `. +:ref:`custom modules `. Threads ======= diff --git a/tutorials/scripting/gdextension/what_is_gdextension.rst b/tutorials/scripting/gdextension/what_is_gdextension.rst index 256566e25..faca4b331 100644 --- a/tutorials/scripting/gdextension/what_is_gdextension.rst +++ b/tutorials/scripting/gdextension/what_is_gdextension.rst @@ -16,7 +16,7 @@ at run-time. You can use it to run native code without compiling it with the eng Differences between GDExtension and C++ modules ----------------------------------------------- -You can use both GDExtension and :ref:`C++ modules ` to +You can use both GDExtension and :ref:`C++ modules ` to run C or C++ code in a Godot project. They also both allow you to integrate third-party libraries into Godot. The one @@ -47,7 +47,7 @@ Also: Advantages of C++ modules ^^^^^^^^^^^^^^^^^^^^^^^^^ -We recommend :ref:`C++ modules ` in cases where +We recommend :ref:`C++ modules ` in cases where GDExtension isn't enough: - C++ modules provide deeper integration into the engine. GDExtension's access is not as deep as