Module XML File Guide¶
Overview¶
This guide explains how to create and maintain module XML files in the ORCA framework. Module XML files are used to define the API interface between C code and Lua, automatically generating C headers, bindings, and HTML documentation.
What Are Module XML Files?¶
Module XML files describe the public API of C modules in a declarative format. The toolchain in tools/ processes these XML files to generate:
- C Header Files (
.h) - Type definitions and function declarations - C Export Files (
_export.c) - Lua bindings and registration code - Properties Headers (
_properties.h) - Property hash constants - API Documentation - Markdown docs at
docs/api/ - DTD Schema - UI component XML schema (generated from module files)
Location and Usage¶
Module XML files are located alongside their corresponding C source code:
source/geometry/geometry.xml- Geometry types (vectors, matrices, etc.)source/core/core.xml- Core engine objects and componentssource/renderer/api/renderer.xml- Rendering interfacesplugins/UIKit/UIKit.xml- UI componentsplugins/SceneKit/SceneKit.xml- 3D scene graph componentsplugins/SpriteKit/SpriteKit.xml- 2D sprite componentssource/filesystem/filesystem.xml- File system access
To generate code from these XML files, run:
XML File Structure¶
Every module XML file must have this basic structure:
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "https://corepunch.github.io/orca/schemas/module.dtd">
<module name="modulename" namespace="orca">
<includes>
<include file="path/to/header.h"/>
</includes>
<externals>
<external struct="ExternalType"/>
</externals>
<enums>
<enum name="MyEnum">...</enum>
</enums>
<structs>
<struct name="MyStruct">...</struct>
</structs>
<interfaces>
<interface name="MyInterface">...</interface>
</interfaces>
<classes>
<class name="MyClass">...</class>
</classes>
<functions>
<function name="MyFunction">...</function>
</functions>
</module>
Type definitions are grouped into typed container elements at the module root. This keeps all enumerations in <enums>, all structs in <structs>, all interfaces in <interfaces>, all components in <classes>, and all global functions in <functions>.
Root Element: <module>¶
The root element defines the module's identity and namespace.
Attributes:
- name (required) - The module name (e.g., "geometry", "core")
- namespace (required) - Lua namespace (typically "orca")
- on-luaopen (optional) - Callback function name to execute when module loads
- prefix (optional) - Prefix for generated C identifiers
Top-Level Container Elements¶
Type definitions at the module level are always wrapped in a typed container:
| Container | Contents | Element type |
|---|---|---|
<enums> |
Enumeration definitions | <enum> |
<structs> |
C struct definitions | <struct> |
<interfaces> |
Abstract interface definitions | <interface> |
<classes> |
Component (class) definitions | <class> |
<functions> |
Global function definitions | <function> |
Type Definition Elements¶
1. <enum> — Enumeration Definitions¶
Defines an enumeration type with named constants.
Attributes:
- name (required) - Name of the enumeration type
Child Elements:
- <summary> - Brief description
- <details> - Detailed explanation
- <value> - Individual enumeration value
Example:
<enums>
<enum name="RotationOrder">
<summary>Euler angle rotation order enumeration</summary>
<value name="XYZ">Rotate around X axis first, then Y, then Z</value>
<value name="XZY">Rotate around X axis first, then Z, then Y</value>
</enum>
</enums>
2. <struct> — Structure Definitions¶
Defines a C struct with fields and methods. Child elements are grouped into container elements.
Attributes:
- name (required) - Name of the struct
- prefix (optional) - Prefix for C constants (e.g., "VEC2_")
- export (optional) - Name exported to Lua (defaults to struct name)
- sealed (optional) - If "true", prevents recursive field access from Lua
Child Elements (in order):
- <summary> - Brief description
- <details> - Detailed explanation
- <fields> - Container for <field> elements
- <methods> - Container for <method> elements
Example:
<structs>
<struct name="vec2" prefix="VEC2_" export="Vector2D" sealed="true">
<summary>2D vector structure</summary>
<details>Represents a point or direction in 2D space.</details>
<fields>
<field type="float" name="x">X coordinate component</field>
<field type="float" name="y">Y coordinate component</field>
</fields>
<methods>
<method name="Add" export="__add" const="true">
<summary>Adds two vectors component-wise</summary>
<arg type="vec2" name="other" pointer="true" const="true">Vector to add</arg>
<returns type="vec2">Sum of the two vectors</returns>
</method>
</methods>
</struct>
</structs>
3. <interface> — Interface Definitions¶
Similar to <struct>, but defines an abstract interface. Methods and topics are grouped in <methods>, messages in <messages>.
Attributes: Same as <struct>, plus:
- no-check (optional) - If "true", skips type checking in generated code
- parent (optional) - Parent interface name
Child Elements (in order):
- <summary> - Brief description
- <details> - Detailed explanation
- <init> - Initialization marker
- <methods> - Container for <method> and <topic> elements
- <messages> - Container for <message> elements
Example (simple):
<interfaces>
<interface name="Object" prefix="OBJ_" export="Object" no-check="true">
<summary>Core engine host object.</summary>
<methods>
<method name="Clear" export="clear" lua="true">
<summary>Clear all children of the object.</summary>
</method>
</methods>
</interface>
</interfaces>
Example (with topic separators):
<interfaces>
<interface name="Object" prefix="OBJ_" export="Object" no-check="true">
<summary>Core engine host object.</summary>
<methods>
<topic title="Lifecycle">Manages object creation, initialization, and destruction.</topic>
<method name="Awake" lua="true">
<summary>Initializes the object when loaded.</summary>
</method>
<method name="Clear" export="clear" lua="true">
<summary>Clear all children of the object.</summary>
</method>
<topic title="Hierarchy">Navigates and manipulates the parent-child relationship tree.</topic>
<method name="AddChild">
<summary>Add a child object.</summary>
<arg name="child" type="Object" pointer="true">The object to add as a child</arg>
</method>
</methods>
<messages>
<message name="Create"/>
<message name="Destroy"/>
</messages>
</interface>
</interfaces>
<topic> — Inline Section Separator¶
A <topic> is a separator placed inside the <methods> container between method elements. It marks the start of a new named section in the generated documentation.
Attributes:
- title (required) - The section heading used in generated documentation
Rules:
- A <topic> may only appear directly inside a <methods> element within an <interface>.
- Methods following a <topic> belong to that section until the next <topic> or the end of <methods>.
- <topic> is invisible to code generation; only docs.php renders topics as section headings.
When to use topics:
- Use topics when an interface has more than ~10 methods with clear functional groups.
- See source/core/core.xml for a real-world example with 10 topic separators.
4. <class> — Component Definitions¶
Defines a component that can be attached to objects. All child element types are grouped into containers.
Attributes:
- name (required) - Component name
- parent (optional) - Parent component to inherit from
- concept (optional) - Interface this component implements
- children (optional) - Type of child nodes this component accepts
- prefix (optional) - Prefix for generated C identifiers
Child Elements (in order):
- <summary> - Brief description
- <details> - Detailed explanation
- <xmlns> - XML namespace declaration for this component
- <handles> - Container for <handle> elements (messages handled by this class)
- <properties> - Container for <property> elements
- <fields> - Container for <field> elements (internal/private data)
- <methods> - Container for <method> elements
- <messages> - Container for <message> elements
Example:
<classes>
<class name="SKNode" parent="Node" children="SKNode">
<summary>Base 2D sprite node with transform and matrix</summary>
<details>Provides fundamental 2D transformation properties.</details>
<handles>
<handle message="Node.UpdateMatrix"/>
</handles>
<properties>
<property name="Position" type="vec2">Position of SKNode in space</property>
<property name="Size" type="vec2">Size of SKNode</property>
</properties>
<fields>
<field name="Matrix" type="mat4">Final combined transformation matrix</field>
<field name="_opacity" type="float"/>
</fields>
<messages>
<message name="Render">
<fields>
<field name="ViewDef" type="ViewDef" pointer="true">The view definition for rendering</field>
</fields>
</message>
</messages>
</class>
</classes>
5. <function> — Global Function Definitions¶
Defines a global function in the module namespace.
Attributes:
- name (required) - Function name
Child Elements:
- <summary>, <details>, <arg>, <returns>
Example:
<functions>
<function name="GetFocus">
<summary>Retrieves currently active object.</summary>
<returns type="Object" pointer="true">Pointer to the focused object</returns>
</function>
</functions>
6. <message> — Message Definitions¶
Declares a message that can be handled by components. Fields inside messages are grouped in a <fields> container.
Attributes:
- name (required) - Message name
- type (optional) - Message parameter type (external struct)
- same-as (optional) - Inherit fields from another message
Child Elements:
- <summary>, <details>
- <fields> - Container for <field> elements
Example:
<message name="PropertyChanged">
<fields>
<field name="Property" type="Property" pointer="true">The property that changed</field>
</fields>
</message>
7. <includes> and <externals> — Include and External Directives¶
C header includes and external type references are grouped into container elements at the module level.
<module name="UIKit" namespace="orca">
<includes>
<include file="include/renderer.h"/>
<include file="source/core/core.h"/>
</includes>
<externals>
<external struct="Object"/>
<external struct="ViewDef"/>
</externals>
<!-- ... -->
</module>
8. <resource> — Resource Type Definitions¶
Declares a resource type that can be loaded by the engine.
Attributes:
- type (required) - Resource type name
- no-lua (optional) - If "true", excludes from Lua bindings
Example:
Child Element Details¶
<field> — Struct/Class Fields¶
Defines a data member. Fields are always inside a <fields> container.
Attributes:
- name (required) - Field name
- type (required) - Data type
- fixed-array (optional) - Array size (if a fixed-size array)
- pointer (optional) - If "true", field is a pointer
- const (optional) - If "true", field is const
Example:
<fields>
<field type="float" name="x">X coordinate component</field>
<field name="children" type="Object" array="true" pointer="true">Child objects</field>
</fields>
<method> — Methods¶
Defines a method or member function. Methods are always inside a <methods> container.
Attributes:
- name (required) - Method name
- export (optional) - Name exported to Lua (e.g., "__add" for operator overloading)
- const (optional) - If "true", method does not modify the object
- lua (optional) - If "true", method is Lua-accessible
- static (optional) - If "true", method is static (no this parameter)
- private (optional) - If "true", method is excluded from public bindings
Child Elements: <summary>, <details>, <arg>, <returns>
Example:
<methods>
<method name="Add" export="__add" const="true">
<summary>Adds two vectors component-wise</summary>
<arg type="vec2" name="other" pointer="true" const="true">Vector to add</arg>
<returns type="vec2">Sum of the two vectors</returns>
</method>
</methods>
<property> — Component Properties¶
Defines a property on a component. Properties are always inside a <properties> container.
Attributes:
- name (required) - Property name
- type (required) - Property data type
- readonly (optional) - If "true", property is read-only
- pointer (optional) - If "true", property holds a pointer
- default (optional) - Default value for the property
- array (optional) - If "true", generates an array property (see below)
Example:
<properties>
<property name="Opacity" type="float" default="1">Opacity of the node.</property>
<property name="Image" type="Texture" pointer="true">Texture to display.</property>
</properties>
Array properties (array="true")¶
Setting array="true" on a <property> declares a dynamically-sized array of the given type. The code generator automatically produces two C struct fields and two property table entries from a single XML declaration:
| Generated name | C type | Description |
|---|---|---|
<Name> |
struct <Type>* |
Pointer to the first element of the heap-allocated array |
Num<Name> |
int32_t |
Number of elements currently stored in the array |
Both are exposed as Lua-accessible properties. There is no separate <property> declaration needed for the count — it is created implicitly.
Example declaration:
<properties>
<property name="Clips" type="AnimationClipReference" array="true">
Named clips available to this player
</property>
</properties>
Generated C struct fields:
struct AnimationPlayer {
struct AnimationClipReference* Clips; /* the array */
int32_t NumClips; /* auto-generated count */
/* … other fields … */
};
Generated property table entries (in *_export.c):
ARRAY_DECL(…, AnimationPlayer, Clips, Clips, kDataTypeStruct, .TypeString = "AnimationClipReference"),
DECL (…, AnimationPlayer, NumClips, NumClips, kDataTypeInt),
Lua usage:
-- Read the count
print(obj.NumClips)
-- The array itself is managed by the engine XML loader;
-- individual entries are accessible via the property system
The same pattern applies to any array="true" property. For example, AnimationCurve.Keyframes generates Keyframes* and NumKeyframes.
<handles> and <handle> — Message Handlers¶
Declares which messages a component handles. The <handles> container holds one or more <handle> children.
<handle> Attributes:
- message (required) - Name of message to handle (format: ClassName.MessageName)
Example:
<arg> — Function/Method Arguments¶
Attributes: name (required), type (required), pointer (optional), const (optional)
<returns> — Return Value¶
Attributes: type (required), pointer (optional), const (optional)
Documentation Elements¶
<summary>- Single-line description<details>- Multi-paragraph description (can contain<p>tags and<snippet>refs)<xmlns>- XML namespace for the component in UI XML files
Common Data Types¶
Primitive Types: bool, int, uint, float, string, void
Geometry Types: vec2, vec3, vec4, rect, mat2, mat3, mat4, color
Engine Types: Object, Texture, Material, and custom types defined in other modules
Example: Complete Module¶
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "https://corepunch.github.io/orca/schemas/module.dtd">
<module name="example" namespace="orca">
<includes>
<include file="source/core/core.h"/>
</includes>
<externals>
<external struct="lua_State"/>
</externals>
<enums name="Direction">
<summary>Cardinal directions</summary>
<enum name="North">Northward direction</enum>
<enum name="South">Southward direction</enum>
</enums>
<struct name="point" export="Point">
<summary>2D point</summary>
<fields>
<field type="int" name="x">X coordinate</field>
<field type="int" name="y">Y coordinate</field>
</fields>
<methods>
<method name="Move">
<summary>Move point in a direction</summary>
<arg type="Direction" name="dir">Direction to move</arg>
<arg type="int" name="distance">Distance to move</arg>
</method>
</methods>
</struct>
<class name="Marker" parent="Node2D">
<summary>A visual marker placed in 2D space</summary>
<handles>
<handle message="Object.Create"/>
</handles>
<properties>
<property name="Color" type="color">Marker color</property>
<property name="Radius" type="float" default="5">Marker radius in pixels</property>
</properties>
<fields>
<field name="_mesh" type="mesh" pointer="true"/>
</fields>
<messages>
<message name="Clicked">
<fields>
<field name="X" type="int">Click X coordinate</field>
<field name="Y" type="int">Click Y coordinate</field>
</fields>
</message>
</messages>
</class>
<function name="CreatePoint">
<summary>Create a new point</summary>
<arg type="int" name="x">Initial X coordinate</arg>
<arg type="int" name="y">Initial Y coordinate</arg>
<returns type="point">New point instance</returns>
</function>
</module>
Schema Validation¶
Module XML files should reference the DTD schema for validation:
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "https://corepunch.github.io/orca/schemas/module.dtd">
Best Practices¶
- Always include documentation — Every element should have at least a
<summary> - Use container elements — Group
<property>,<field>,<method>,<message>and<handle>elements inside their respective container elements (<properties>,<fields>,<methods>,<messages>,<handles>) - Use
<topic>for large interfaces — If a<methods>block has more than ~10 methods, add<topic title="...">separators between method groups (Lifecycle, Hierarchy, etc.) - Follow element order — For
<class>: summary, details, xmlns, handles, properties, fields, methods, messages. For<struct>: summary, details, fields, methods - Test generation — Run
cd tools && makeafter changes to verify XML is valid - Check generated code — Review generated
.hand_export.cfiles to ensure correctness
Troubleshooting¶
Error: "Expected 'module' tag"
- Ensure your root element is <module>
Missing functions in Lua
- Ensure the export attribute is set correctly on the method/function
- Verify lua="true" is set for Lua-accessible methods
Type errors in generation
- Verify all referenced types are defined (in this module or via <externals>)
- Ensure <includes> directives are present for external headers
Fields not appearing in struct
- Ensure <field> elements are inside a <fields> container directly in the struct or class
- Fields inside <message> elements are message parameters, not struct members
Further Reading¶
- See existing module XML files in
source/andplugins/for real-world examples - Check
docs/schemas/module.dtdfor the complete schema definition - See
tools/model/module.phpfor the PHP data model that parses XML files - See
tools/templates/for the code generation templates