Wrapper Maintenance¶
This page is for Kanama maintainers working on generated wrappers, KDoc, or API refreshes. Game projects do not need these commands.
Generator Role¶
The wrapper generator turns Godot's extension_api.json into conservative
Kotlin wrapper drafts. Its job is to scale API coverage without hand-writing
thousands of MethodBind calls, while refusing shapes where Kanama has not
defined ABI, ownership, or marshalling policy yet.
Generated drafts are not automatically promoted. A class only becomes public source after review, smoke coverage where practical, and reproducibility checks against the generator output. This keeps broad wrapper growth auditable instead of relying on one-off manual wrappers.
Refreshing generated Panama bindings from a new Godot API/header set requires
jextract 25+. Normal game projects do not run jextract; it is only part of
Kanama's API/header refresh workflow.
Wrapper Guardrails¶
Kanama's conservative wrapper generator is intentionally fail-loud. CI checks the generated method shapes against the runtime FFM helpers, including int32/int64 width, float/double layout, packed-array storage, generic Array/Dictionary/Variant policy, and Callable blocking.
Generated public APIs must keep concrete Godot object types concrete. For
example, a Godot Node3D return should render as Node3D?, not
GodotObject, Object, or MemorySegment. Exact Godot Object APIs remain
dynamic because the engine itself does not promise a more specific type.
Ownership-sensitive namespace-style types use explicit policy before default
generation. Callable stays blocked unless a helper has a bounded ownership
shape; DirAccess, FileAccess, and SceneTree use dedicated handle aliases
where factory methods return nullable object handles.
Promoted generated wrappers are intentionally allowlisted. The generator can
emit selected classes with --emit-class, and
scripts/check_wrapper_generator.py compares allowlisted promoted source files
against freshly generated output so manual edits and generator drift fail
loudly. Adopted classes with skipped methods are only accepted when every skip
is a Godot virtual callback that belongs to the future override-registration
design rather than the public ptrcall wrapper surface.
Engine-wide MethodName, PropertyName, and SignalName constants are
generated from extension_api.json separately from the class wrapper drafts:
python3 scripts/generate_name_constants.py
scripts/check_wrapper_generator.py runs the same generator in --check mode,
so a Godot API refresh fails loudly if the committed name constants are stale.
Coverage Triage¶
For v0.3.0 wrapper work, use the coverage reports as the baseline instead of waiting for another demo to expose a gap:
- Refresh
docs/reference/api-coverage.mdanddocs/reference/wrapper-generator-report.md. - Start from the generator skip categories and missing helper shapes.
- Rank gaps by common Godot workflows: scene tree, resources, physics queries, animation, UI, input, materials, signals, RPC, and export-facing APIs.
- Prefer removing raw escape hatches (
Object.call,Object.get,Object.set, string method names, manual handle casts) from normal user workflows over broad class-count increases. - Use public demos as regression coverage after choosing a wrapper slice, not as the only source of wrapper priorities.
The current coverage pages already separate promoted source coverage from generator capability. Treat low-coverage areas such as variant/dictionary helper shapes, typed arrays, and multiplayer/editor methods as API design work: add helper policy and audits before promoting wider wrappers.
KDoc Maintenance¶
Public Godot-backed wrappers and builtin value types carry generated KDoc
imported from Godot's doc/classes/*.xml files. The generated blocks include a
Generated from Godot docs: marker so they can be refreshed safely instead of
hand-edited.
To check whether KDoc is current against a local Godot source tree:
python3 scripts/sync_kdoc_from_godot_docs.py --check
To refresh it:
python3 scripts/sync_kdoc_from_godot_docs.py --write
The script uses $GODOT_DOCS when set, otherwise it defaults to
godot/doc/classes relative to the current working directory. Use
--godot-docs /path/to/godot/doc/classes when syncing against a different
Godot checkout. Use --classes Node,Node3D,Tween for a focused refresh while
working on one wrapper slice, or --scope types --classes Vector3 when
working on builtin values.
Value-Type Audits¶
Value-type helpers that mirror Godot builtin methods should call the matching
Godot builtin unless the local implementation is deliberately proven equivalent.
Use the audit script when editing types/*.kt:
python3 scripts/audit_value_type_wrappers.py --api extension_api.json
The audit is report-only by default, and --strict is wired into local CI.
Reviewed local scalar formulas are allowlisted in the script; any newly added
Godot-named value helper that does not call the builtin should be treated as
suspicious until it is either bound to Godot's builtin or deliberately added to
the reviewed list with focused parity evidence.
For scalar Godot float method arguments, keep using the separate ABI guard:
python3 scripts/audit_scalar_float_abi.py
Godot's scalar float ptrcall slot is 64-bit (JAVA_DOUBLE) even when
single-precision real_t value components are Float.