Repository navigation
Generating Bindings
A quick-start companion to the Generated Bindings Guide — this page answers "which command do I run and why", the full guide covers packaging the output into a DLL and consuming it from game scripts.
The binding generator (Code/Tools/BindingGenerator/O3DESharp.BindingGenerator/) can produce C# bindings two different ways, selected with --source:
--source reflection (default) |
--source clang |
|
|---|---|---|
| Reads |
reflection_data.json — a dump of O3DE's BehaviorContext produced by the editor at runtime |
Your C++ headers directly, via ClangSharp / libclang |
| Same data as | Lua, ScriptCanvas, Python bindings | Nothing else — this is its own parse pass |
| Prerequisite | Launch the O3DE Editor for your project once, so AutoExportReflectionData writes reflection_data.json
|
None beyond the headers themselves |
| Use for | Anything a C# script would actually want to call — this is the recommended default | A type a component exposes in its header but hasn't reflected to BehaviorContext yet |
| Cost | Lightweight — no header parsing, no MSVC compatibility fights, no cross-gem include walking | Heavier; can generate wrappers with no matching BehaviorContext dispatch path, which crash at runtime if called |
If you're not sure which one you need, use reflection. Reach for clang only when reflection can't see the type you need because it isn't reflected yet.
Earlier versions of this gem shipped a separate Python binding generator under
Editor/Scripts/that consumed areflection_data.jsondump directly. That generator is deprecated and removed — the Python files remaining there are thin orchestrators that shell out to the C# tool described on this page.
# 1. Build the tool (first time only)
cd Gems/O3DESharp/Code/Tools/BindingGenerator/O3DESharp.BindingGenerator
dotnet build -c Release
# 2. Launch the O3DE Editor for your project at least once, so it writes
# reflection_data.json — then generate bindings from it:
dotnet run -- generate \
--project <path-to-your-O3DE-project> \
--source reflection \
--reflection-data <path-to-your-O3DE-project>/Generated/reflection_data.jsonAlways pass --reflection-data explicitly — the CLI's built-in default search path isn't guaranteed to match where your project's editor build actually wrote the file.
# All enabled gems
dotnet run -- generate --project <path-to-your-O3DE-project> --source clang
# Specific gems only
dotnet run -- generate --project <path> --source clang --gems MyGem,PhysicsGem
# Force a full regeneration (skip the incremental cache)
dotnet run -- generate --project <path> --source clang --verbose --forceThe clang backend is configured via binding_config.json at the repo root — header glob patterns, include paths, defines, and per-gem overrides. See the Generated Bindings Guide for the full schema.
Both emit into the same shape: InternalCalls.g.cs (the raw delegate* unmanaged<> function pointers), one {ClassName}.g.cs wrapper per reflected type, enums, a {GemName}.csproj ready to compile into a DLL, plus the C++-side registration glue the clang backend additionally needs (BindingRegistration.g.cpp, hot-reload hooks). Once you have .g.cs files, packaging them into a DLL and referencing that DLL from your game scripts is the same process either way — that's the Generated Bindings Guide's job, starting at "Packaging Generated Bindings into a DLL".
The generator is wired into CMake as the O3DESharp.GenerateBindings target and runs automatically on build when O3DESHARP_AUTO_GENERATE_BINDINGS=ON (the default), driven by binding_config.json at the repo root — this uses the clang backend. For automatic regeneration tied into a game project's own dotnet build (including design-time IntelliSense builds), see the Generated Bindings Guide's MSBuild task integration section.
From the editor menu (interactive use): Tools → C# Bindings → Generate Bindings.
See the Generated Bindings Guide's Troubleshooting section for the full list (skipped template/container types, filename sanitization, libclang not found, stale bindings). The two most common first-run issues:
-
"No bindings generated" on the reflection backend — you likely haven't launched the Editor yet, or
--reflection-datadoesn't point at the file it wrote. Confirm the path exists before rerunning. -
"No bindings generated" on the clang backend — check
binding_config.jsonlists your gem undergemswith"enabled": true, and thatheaderPatternsactually match your header locations (--verboseshows what the parser scanned).