From godot-prompter
Builds native Godot extensions in C++ or Rust for performance-critical code, library wrapping, or language bindings without recompiling the engine.
How this skill is triggered — by the user, by Claude, or both
Slash command
/godot-prompter:gdextensionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Run native C++ (or Rust) in Godot as a shared library **without recompiling the engine**. Use it for performance-critical code, wrapping existing C/C++ libraries, or language bindings.
Run native C++ (or Rust) in Godot as a shared library without recompiling the engine. Use it for performance-critical code, wrapping existing C/C++ libraries, or language bindings.
Related skills: csharp-godot for when C# is enough, gdscript-advanced for GDScript performance idioms first, godot-optimization for profiling before going native, addon-development for distributing the result, export-pipeline for shipping the binaries.
Reach for GDScript or C# for almost all game logic. Choose GDExtension only when you genuinely need it:
Contrast with C++ modules, which are compiled into the engine and therefore require shipping a custom engine binary. GDExtension's key advantage is that it runs against a stock Godot — you distribute just a shared library. It is "more complicated to use than GDScript and C#," so don't reach for it by default.
mkdir gdextension_example && cd gdextension_example
git init
# IMPORTANT: use the godot-cpp branch matching your target engine version (e.g. 4.3),
# not the literal "4.x".
git submodule add -b 4.3 https://github.com/godotengine/godot-cpp
cd godot-cpp && git submodule update --init && cd ..
Directory layout:
gdextension_example/
├── project/ # demo project to test the extension
│ └── bin/example.gdextension
├── godot-cpp/ # C++ bindings (submodule)
└── src/
├── register_types.{h,cpp}
└── gdexample.{h,cpp}
Build with scons platform=<platform> (omit the platform to target the current one; default build is debug). The official SConstruct is a downloadable file from the C++ tutorial rather than hand-rolled here — follow godot-cpp's build docs. SCons is the official path; godot-cpp also supports CMake.
Header (gdexample.h):
#pragma once
#include <godot_cpp/classes/sprite2d.hpp>
namespace godot {
class GDExample : public Sprite2D {
GDCLASS(GDExample, Sprite2D)
private:
double time_passed = 0.0;
double amplitude = 10.0;
double speed = 1.0;
protected:
static void _bind_methods();
public:
void _process(double delta) override;
void set_amplitude(double p_amplitude);
double get_amplitude() const;
void set_speed(double p_speed);
double get_speed() const;
};
}
Bindings (gdexample.cpp — _bind_methods):
void GDExample::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_amplitude"), &GDExample::get_amplitude);
ClassDB::bind_method(D_METHOD("set_amplitude", "p_amplitude"), &GDExample::set_amplitude);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "amplitude"), "set_amplitude", "get_amplitude");
ClassDB::bind_method(D_METHOD("get_speed"), &GDExample::get_speed);
ClassDB::bind_method(D_METHOD("set_speed", "p_speed"), &GDExample::set_speed);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE, "0,20,0.01"),
"set_speed", "get_speed");
ADD_SIGNAL(MethodInfo("position_changed",
PropertyInfo(Variant::OBJECT, "node"),
PropertyInfo(Variant::VECTOR2, "new_pos")));
}
The patterns:
GDCLASS(Class, Parent) — first line of every native class body; wires up the type into Godot's ClassDB.ClassDB::bind_method(D_METHOD("name", "arg"), &Class::method) — exposes a method (and names its arguments) so GDScript/C#/the editor can call it.ADD_PROPERTY(PropertyInfo(...), setter, getter) — registers an Inspector property; bind the getter and setter first, then reference them here by name.PROPERTY_HINT_RANGE with "0,20,0.01" turns the Inspector field into a slider (min, max, step).ADD_SIGNAL(MethodInfo("name", PropertyInfo(...), ...)) — declares a signal with typed arguments; emit it from code with emit_signal("position_changed", this, new_pos).Entry point (register_types.cpp):
void initialize_example_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) return;
GDREGISTER_CLASS(GDExample);
}
void uninitialize_example_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) return;
}
extern "C" {
GDExtensionBool GDE_EXPORT example_library_init(
GDExtensionInterfaceGetProcAddress p_get_proc_address,
const GDExtensionClassLibraryPtr p_library,
GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
init_obj.register_initializer(initialize_example_module);
init_obj.register_terminator(uninitialize_example_module);
init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
return init_obj.init();
}
}
The .gdextension file (project/bin/example.gdextension):
[configuration]
entry_symbol = "example_library_init"
compatibility_minimum = "4.3"
reloadable = true
[libraries]
macos.debug = "res://bin/libgdexample.macos.template_debug.dylib"
macos.release = "res://bin/libgdexample.macos.template_release.dylib"
windows.debug.x86_64 = "res://bin/gdexample.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "res://bin/gdexample.windows.template_release.x86_64.dll"
linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
The exported extern "C" symbol name must equal entry_symbol, or the extension won't load. Register classes with GDREGISTER_CLASS, gated on MODULE_INITIALIZATION_LEVEL_SCENE. The [libraries] keys are platform.feature.arch tags; template_debug / template_release distinguish build configs. Optional sections: [icons] (per-node editor icon) and [dependencies] (extra libs copied on export).
Forward-but-not-backward. An extension targeting 4.2 works in 4.3, but one targeting 4.3 will not load in 4.2. Exception: extensions targeting 4.0 do not work in 4.1+.
reloadable = true hot reload works in debug builds only.compatibility_minimum to the lowest engine version you actually support — too low and the extension fails to load at runtime.template_release binaries present, or the native node type simply won't exist at runtime.After building and placing the .gdextension file, the native class appears as a normal node type: bound properties show up in the Inspector (range hints become sliders) and signals appear in the Node dock.
extends Node
func _ready():
var node := GDExample.new()
node.speed = 2.0
node.position_changed.connect(_on_position_changed)
add_child(node)
func _on_position_changed(node, new_pos):
print("%s is now at %s" % [node.get_class(), new_pos])
using Godot;
public partial class Demo : Node
{
public override void _Ready()
{
var node = new GDExample(); // The native class is available like any Godot type.
node.Set("speed", 2.0);
node.Connect("position_changed", Callable.From<Node, Vector2>(OnPositionChanged));
AddChild(node);
}
private void OnPositionChanged(Node node, Vector2 newPos)
=> GD.Print($"{node.GetClass()} is now at {newPos}");
}
To get a strongly-typed C# wrapper you can ship a C# glue class, but the extension is fully usable via the dynamic Set / Connect / Call API shown above.
Other languages & debugging: Rust (gdext) · Debugging native code
_bind_methods binds every exposed method/property/signalentry_symbol in .gdextension matches the exported extern "C" symbolcompatibility_minimum set to the lowest engine version you support[libraries] has correct paths for every shipped platform/arch (debug + release)template_release binariesnpx claudepluginhub jame581/godotprompter --plugin godot-prompterExplains C#-specific conventions, API differences from GDScript, project setup, and interop for Godot 4.3+.
Provides Godot 4 GDScript patterns for architecture, signals, scenes, state machines, and optimization. Useful for building games, game systems, and best practices.
Generates idiomatic Godot 4.x GDScript code with type hints, annotations, signals, and patterns for CharacterBody2D/3D movement and state machines.