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 Redot.
Checking the stable version of the documentation...
Redot Android plugins¶
Introduction¶
Android plugins are powerful tools to extend the capabilities of the Redot engine by tapping into the functionality provided by Android platforms and ecosystem.
For example in Redot 4, Android plugins are used to support multiple Android-based XR platforms without encumbering the core codebase with vendor specific code or binaries.
Android plugin¶
Version 1 (v1) of the Android plugin system was introduced in Redot 3 and compatible with Redot 4.0 and 4.1. That version allowed developers to augment the Redot engine with Java, Kotlin and native functionality.
Starting in Redot 4.2, Android plugins built on the v1 architecture are now deprecated. Instead, Redot 4.2 introduces a new Version 2 (v2) architecture for Android plugins.
v2 Architecture¶
Note
Redot Android plugin leverages the Gradle build system.
Building on the previous v1 architecture, Android plugins continue to be derived from the Android archive library.
At its core, a Redot Android plugin v2 is an Android library with a dependency on the Redot Android library, and a custom Android library manifest.
This architecture allows Android plugins to extend the functionality of the engine with:
Android platform APIs
Android libraries
Kotlin and Java libraries
Native libraries (via JNI)
GDExtension libraries
Each plugin has an init class extending from the GodotPlugin class which is provided by the Redot Android library.
The GodotPlugin
class provides APIs to access the running Redot instance and hook into its lifecycle. It is loaded at runtime by the Redot engine.
v2 Packaging format¶
v1 Android plugins required a custom gdap
configuration file that was used by the Redot Editor to detect and load them.
However this approach had several drawbacks, primary ones being that it lacked flexibility and departed from the existing
Redot EditorExportPlugin format, delivery and installation flow.
This has been resolved for v2 Android plugins by deprecating the gdap
packaging and configuration mechanism in favor of
the existing Redot EditorExportPlugin
packaging format.
The EditorExportPlugin
API in turn has been extended to properly support Android plugins.
Building a v2 Android plugin¶
A github project template is provided at https://github.com/m4gr3d/Godot-Android-Plugin-Template as a quickstart for building Redot Android plugins for Redot 4.2+. You can follow the template README to set up your own Redot Android plugin project.
To provide further understanding, here is a break-down of the steps used to create the project template:
Create an Android library module using these instructions
Add the Redot Android library as a dependency by updating the module's
gradle
build file:dependencies { implementation("org.godotengine:godot:4.2.0.stable") }
The Redot Android library is hosted on MavenCentral, and updated for each release.
Create GodotAndroidPlugin, an init class for the plugin extending GodotPlugin.
If the plugin exposes Kotlin or Java methods to be called from GDScript, they must be annotated with @UsedByRedot. The name called from GDScript must match the method name exactly. There is no coercing
snake_case
tocamelCase
. For example, from GDScript:if Engine.has_singleton("MyPlugin"): var singleton = Engine.get_singleton("MyPlugin") print(singleton.myPluginFunction("World"))
If the plugin uses signals, the init class must return the set of signals used by overriding GodotPlugin::getPluginSignals(). To emit signals, the plugin can use the GodotPlugin::emitSignal(...) method.
Update the plugin
AndroidManifest.xml
file with the following meta-data:<meta-data android:name="org.godotengine.plugin.v2.[PluginName]" android:value="[plugin.init.ClassFullName]" />
Where:
PluginName
is the name of the plugin
plugin.init.ClassFullName
is the full component name (package + class name) of the plugin init class (e.g:org.godotengine.plugin.android.template.GodotAndroidPlugin
).
Create the EditorExportPlugin configuration to package the plugin. The steps used to create the configuration can be seen in the Packaging a v2 Android plugin section.
Building a v2 Android plugin with GDExtension capabilities¶
Similar to GDNative support in v1 Android plugins, v2 Android plugins support the ability to integrate GDExtension capabilities.
A github project template is provided at https://github.com/m4gr3d/GDExtension-Android-Plugin-Template as a quickstart for building GDExtension Android plugins for Redot 4.2+. You can follow the template's README to set up your own Redot Android plugin project.
Migrating a v1 Android plugin to v2¶
Use the following steps if you have a v1 Android plugin you want to migrate to v2:
Update the plugin's manifest file:
Change the
org.godotengine.plugin.v1
prefix toorg.godotengine.plugin.v2
Update the Redot Android library build dependency:
You can continue using the
godot-lib.<version>.<status>.aar
binary from Redot's download page if that's your preference. Make sure it's updated to the latest stable version.Or you can switch to the MavenCentral provided dependency:
dependencies { implementation("org.godotengine:godot:4.2.0.stable") }
After updating the Redot Android library dependency, sync or build the plugin and resolve any compile errors:
The
Godot
instance provided byGodotPlugin::getGodot()
no longer has access to aandroid.content.Context
reference. UseGodotPlugin::getActivity()
instead.
Delete the
gdap
configuration file(s) and follow the instructions in the Packaging a v2 Android plugin section to set up the plugin configuration.
Packaging a v2 Android plugin¶
As mentioned, a v2 Android plugin is now provided to the Redot Editor as an EditorExportPlugin
plugin, so it shares a lot of the same packaging steps.
Add the plugin output binaries within the plugin directory (e.g: in
addons/<plugin_name>/
)Add the tool script for the export functionality within the plugin directory (e.g: in
addons/<plugin_name>/
)The created script must be a
@tool
script, or else it will not work properlyThe export tool script is used to configure the Android plugin and hook it within the Redot Editor's export process. It should look something like this:
@tool extends EditorPlugin # A class member to hold the editor export plugin during its lifecycle. var export_plugin : AndroidExportPlugin func _enter_tree(): # Initialization of the plugin goes here. export_plugin = AndroidExportPlugin.new() add_export_plugin(export_plugin) func _exit_tree(): # Clean-up of the plugin goes here. remove_export_plugin(export_plugin) export_plugin = null class AndroidExportPlugin extends EditorExportPlugin: # Plugin's name. var _plugin_name = "<plugin_name>" # Specifies which platform is supported by the plugin. func _supports_platform(platform): if platform is EditorExportPlatformAndroid: return true return false # Return the paths of the plugin's AAR binaries relative to the 'addons' directory. func _get_android_libraries(platform, debug): if debug: return PackedStringArray(["<paths_to_debug_android_plugin_aar_binaries>"]) else: return PackedStringArray(["<paths_to_release_android_plugin_aar_binaries>"]) # Return the plugin's name. func _get_name(): return _plugin_name
Here are the set of EditorExportPlugin APIs most relevant to use in this tool script:
_supports_platform: returns
true
if the plugin supports the given platform. For Android plugins, this must returntrue
whenplatform
is EditorExportPlatformAndroid_get_android_libraries: retrieve the local paths of the Android libraries binaries (AAR files) provided by the plugin
_get_android_dependencies: retrieve the set of Android maven dependencies (e.g: org.godot.example:my-plugin:0.0.0) provided by the plugin
_get_android_dependencies_maven_repos: retrieve the urls of the maven repos for the android dependencies provided by
_get_android_dependencies
_get_android_manifest_activity_element_contents: update the contents of the <activity> element in the generated Android manifest
_get_android_manifest_application_element_contents: update the contents of the <application> element in the generated Android manifest
_get_android_manifest_element_contents: update the contents of the <manifest> element in the generated Android manifest
The
_get_android_manifest_*
methods allow the plugin to automatically provide changes to the app's manifest which are preserved when the Redot Editor is updated, resolving a long standing issue with v1 Android plugins.
Create a
plugin.cfg
. This is an INI file with metadata about your plugin:[plugin] name="<plugin_name>" description="<plugin_description>" author="<plugin_author>" version="<plugin_version>" script="<relative_path_to_the_export_tool_script>"
For reference, here is the folder structure for the Redot Android plugin project template.
At build time, the contents of the export_scripts_template
directory as well as the generated plugin binaries are copied to the addons/<plugin_name>
directory:
export_scripts_template/
|
+--export_plugin.gd # export plugin tool script
|
+--plugin.cfg # plugin INI file
Packaging a v2 Android plugin with GDExtension capabilities¶
For GDExtension, we follow the same steps as for Packaging a v2 Android plugin and add the GDExtension config file in
the same location as plugin.cfg
.
For reference, here is the folder structure for the GDExtension Android plugin project template.
At build time, the contents of the export_scripts_template
directory as well as the generated plugin binaries are copied to the addons/<plugin_name>
directory:
export_scripts_template/
|
+--export_plugin.gd # export plugin tool script
|
+--plugin.cfg # plugin INI file
|
+--plugin.gdextension # GDExtension config file
Here is what the plugin.gdextension
config file should look like:
[configuration]
entry_symbol = "plugin_library_init"
compatibility_minimum = "4.2"
android_aar_plugin = true
[libraries]
android.debug.arm64 = "res://addons/GDExtensionAndroidPluginTemplate/bin/debug/arm64-v8a/libGDExtensionAndroidPluginTemplate.so"
android.release.arm64 = "res://addons/GDExtensionAndroidPluginTemplate/bin/release/arm64-v8a/libGDExtensionAndroidPluginTemplate.so"
...
Of note is the android_aar_plugin
field that specifies this GDExtension module is provided as part of a v2 Android plugin.
During the export process, this will indicate to the Redot Editor that the GDExtension native shared libraries are exported by the Android plugin AAR binaries.
For GDExtension Android plugins, the plugin init class must override GodotPlugin::getPluginGDExtensionLibrariesPaths(),
and return the paths to the bundled GDExtension libraries config files (*.gdextension
).
The paths must be relative to the Android library's assets
directory.
At runtime, the plugin will provide these paths to the Redot engine which will use them to load and initialize the bundled GDExtension libraries.
Using a v2 Android plugin¶
Note
Redot 4.2 or higher is required
v2 Android plugin requires the use of the Gradle build process.
The provided github project templates include demo Redot projects for quick testing.
Copy the plugin's output directory (
addons/<plugin_name>
) to the target Redot project's directoryOpen the project in the Redot Editor; the Editor should detect the plugin
Navigate to
Project
->Project Settings...
->Plugins
, and ensure the plugin is enabledInstall the Redot Android build template by clicking on
Project
->Install Android Build Template...
Navigate to
Project
->Export...
In the
Export
window, create anAndroid export preset
In the
Android export preset
, scroll toGradle Build
and setUse Gradle Build
totrue
Update the project's scripts as needed to access the plugin's functionality. For example:
if Engine.has_singleton("MyPlugin"): var singleton = Engine.get_singleton("MyPlugin") print(singleton.myPluginFunction("World"))
Connect an Android device to your machine and run the project on it
Using a v2 Android plugin as an Android library¶
Since they are also Android libraries, Redot v2 Android plugins can be stripped from their EditorExportPlugin
packaging and provided as raw AAR
binaries for use as libraries alongside the Redot Android library by Android apps.
If targeting this use-case, make sure to include additional instructions for how the AAR
binaries should be included (e.g: custom additions to the Android app's manifest).
Reference implementations¶
Tips and Guidelines¶
Simplify access to the exposed Java / Kotlin APIs¶
To make it easier to access the exposed Java / Kotlin APIs in the Redot Editor, it's recommended to provide one (or multiple) gdscript wrapper class(es) for your plugin users to interface with.
For example:
class_name PluginInterface extends Object
## Interface used to access the functionality provided by this plugin.
var _plugin_name = "GDExtensionAndroidPluginTemplate"
var _plugin_singleton
func _init():
if Engine.has_singleton(_plugin_name):
_plugin_singleton = Engine.get_singleton(_plugin_name)
else:
printerr("Initialization error: unable to access the java logic")
## Print a 'Hello World' message to the logcat.
func helloWorld():
if _plugin_singleton:
_plugin_singleton.helloWorld()
else:
printerr("Initialization error")
Support using the GDExtension functionality in the Redot Editor¶
If planning to use the GDExtension functionality in the Redot Editor, it is recommended that the GDExtension's native binaries are compiled not just for Android, but also for the OS onto which developers / users intend to run the Redot Editor. Not doing so may prevent developers / users from writing code that accesses the plugin from within the Redot Editor.
This may involve creating dummy plugins for the host OS just so the API is published to the editor. You can use the godot-cpp-template github template for reference on how to do so.
Redot crashes upon load¶
Check adb logcat
for possible problems, then:
Check that the methods exposed by the plugin used the following Java types:
void
,boolean
,int
,float
,java.lang.String
,org.godotengine.godot.Dictionary
,int[]
,byte[]
,float[]
,java.lang.String[]
.More complex datatypes are not supported for now.