GDNative Runtime Loader
Allows for runtime loading of GDNative libraries for Godot 3.4.x.
Useful for making parts of your game/application optional to users. An example of where this would be useful would be making a lip-sync library optional or using a mock library if it's not available.
Note
This script is really only useful for exported projects that wish to make some features optional. If possible, you should instead rely on CICD to package your game/app appropriately.
Limitations
- The library must be exposed to Godot using GDNative
- If a library is unloaded at runtime, your game/app will probably crash
- The runtime loader must be used to interact with your library
Example
GDScript
runtime_loader = RuntimeLoader.new("res://example/plugins/" if OS.is_debug_build() else "")
runtime_loader.scan()
pinger = runtime_loader.create_class("pinger", "Pinger")
if pinger != null:
print(pinger.ping())
config.ini
# Library metadata that's technically optional
# If omitted, defaults will be used, however it's generally better to be explicit
[General]
# These all map back to GDNativeLibrary resource properties
symbol_prefix="godot_"
reloadable=true
load_once=true
singleton=false
# Only use the following option if you are sure you need it
init_func_name="my_init_func"
# A section must exist for each target platform
# Target platform names map back to the names in a GDNativeLibrary resource
[Windows.64]
# The name of the library in the current folder
# In theory, this will also work in a nested folder as long as you provide a relative path
lib="rust.dll"
# All other sections are used to define classes in the library
[Pinger]
# This is the only field needed in order to generate a NativeScript resource
extends="Reference"
A full example is provided as a release. The ponger
library is deliberately misconfigured in order to showcase error handling. It is trivial to fix. If you cannot figure out how to fix ponger
's configuration, this addon is too advanced for you.
Quickstart
- Copy the
addons/gdnative-runtime-library
directory into your addons folder - Create a
plugins
folder at your project root (next to your executable for exported projects) - Create a new folder for each of your plugins
- Add a
config.ini
file for each plugin (e.g.plugins/my_gdnative_lib/config.ini
) - Fill out the
config.ini
(see theexample
project for an example. Note that thedll
s are not checked into this repository, but you can download the exported release for a runnable example) - Create a new
gdnative_runtime_loader.gd
file with an optionalpath
arg (By default this searches for aplugins
folder at your project root, but this can be customized) - Call
scan()
in order to parse the libraries - If your library has a custom
init
hook, you will need to pass those args now to the library (e.g.runtime_loader.libraries["my_lib"].add_init_arg(1))
to add an init arg1
to a library calledmy_lib
) - Create classes defined in your library and use them in your game/app (e.g.
runtime_loader.create_class("my_lib", "foo")
to create a class calledFoo
from themy_lib
library)