Skip to content

Generating Bindings

Mikael K. Aboagye edited this page Aug 25, 2026 · 1 revision

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.

Two backends — pick one

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 a reflection_data.json dump 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.

Quick start: reflection backend (recommended)

# 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.json

Always 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.

Quick start: clang backend

# 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 --force

The 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.

What either backend produces

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".

Automatic generation

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.

Troubleshooting

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-data doesn't point at the file it wrote. Confirm the path exists before rerunning.
  • "No bindings generated" on the clang backend — check binding_config.json lists your gem under gems with "enabled": true, and that headerPatterns actually match your header locations (--verbose shows what the parser scanned).

Clone this wiki locally