| name | add-lua-binding-complex |
| description | Add comprehensive Cataclysm-BN Lua bindings for complex C++ classes with methods, inheritance, constructors, properties, operators, and ownership rules. |
| metadata | {"argument-hint":"ClassName [binding-file]"} |
Add Complex Lua Binding
This skill helps you create comprehensive Lua bindings for complex C++ classes including:
- Classes with methods and properties
- Inheritance hierarchies
- Constructors and factory methods
- Custom operators
Planning Your Binding
Before you start, determine:
- Class name and Lua name
- Base classes (if any)
- Constructors to expose
- Methods to expose (public API)
- Properties to expose
- Target file (
catalua_bindings_*.cpp - group by domain)
Step-by-Step Process
1. Add Luna Documentation Macro
In src/catalua_luna_doc.h:
LUNA_DOC( my_class, "MyClass" )
LUNA_PTR_VAL( my_class, "MyClass" )
2. Choose/Create Binding File
Files are organized by domain:
catalua_bindings_creature.cpp - Creature, Character, Player, Avatar, NPC
catalua_bindings_item.cpp - Item and related
catalua_bindings_map.cpp - Map, terrain, furniture
catalua_bindings_*.cpp - Create new if needed
3. Include Required Headers
At top of binding file:
#include "catalua_bindings.h"
#include "catalua_bindings_utils.h"
#include "catalua_luna.h"
#include "catalua_luna_doc.h"
#include "my_class.h"
4. Create Registration Function
auto cata::detail::reg_my_domain( sol::state &lua ) -> void
{
#define UT_CLASS my_class
{
DOC( "Description of MyClass" );
DOC( "Additional documentation lines" );
auto ut = luna::new_usertype<UT_CLASS>(
lua,
luna::bases<base_class>(),
luna::constructors<
UT_CLASS(),
UT_CLASS( const UT_CLASS & ),
UT_CLASS( int, std::string )
>()
);
SET_MEMB( my_field );
SET_MEMB_RO( readonly_field );
SET_FX( simple_method );
SET_FX_T( overloaded_method, int( std::string ) const );
luna::set_fx( ut, "custom_method",
[]( UT_CLASS &self, int arg ) -> std::string { return self.internal_method( arg ); }
);
luna::set_fx( ut, "static_factory", &UT_CLASS::create );
luna::set_fx( ut, sol::meta_function::equal_to, &UT_CLASS::operator== );
luna::set_fx( ut, sol::meta_function::less_than, &UT_CLASS::operator< );
luna::set_fx( ut, sol::meta_function::to_string,
[]( const UT_CLASS &obj ) -> std::string { return obj.to_string(); }
);
}
#undef UT_CLASS
}
5. Register in Main Binding Function
In src/catalua_bindings.h:
namespace cata::detail {
void reg_my_domain( sol::state &lua );
}
In src/catalua_bindings.cpp, in reg_all_bindings():
void cata::detail::reg_all_bindings( sol::state &lua ) {
reg_my_domain( lua );
}
Advanced Patterns
Handling Inheritance
luna::new_usertype<base_class>(
lua,
luna::no_bases,
luna::no_constructor
);
luna::new_usertype<derived_class>(
lua,
luna::bases<base_class>(),
luna::no_constructor
);
Detached Pointers (Lua ownership)
For objects that Lua can own:
luna::set_fx( ut, "remove_item",
[]( character &ch, item &it ) -> detached_ptr<item> {
return detached_ptr<item>( ch.remove_item( it ) );
}
);
luna::set_fx( ut, "add_item",
[]( character &ch, detached_ptr<item> it ) {
ch.add_item( std::move( it ) );
}
);
Optional Parameters and Return Values
luna::set_fx( ut, "method_with_optional",
[]( UT_CLASS &self, int required, sol::optional<std::string> opt ) {
if( opt ) {
self.do_something( required, *opt );
} else {
self.do_something( required );
}
}
);
luna::set_fx( ut, "maybe_get_value",
&UT_CLASS::try_get_value
);
Variadic Arguments
luna::set_fx( ut, "variadic_method",
[]( UT_CLASS &self, sol::variadic_args va ) {
for( auto arg : va ) {
}
}
);
Exposing Collections
luna::set_fx( ut, "get_items",
&UT_CLASS::get_items
);
luna::set_fx( ut, "get_stats",
&UT_CLASS::get_stats
);
Documentation with Parameters
DOC( "Applies damage to a body part" );
DOC_PARAMS(
"attacker: Creature - The attacking creature",
"bp: BodyPartTypeIntId - Target body part",
"damage: DamageInstance - Damage to apply"
);
luna::set_fx( ut, "apply_damage", &UT_CLASS::apply_damage );
Method Signature Resolution
When a method has overloads, use sol::resolve:
SET_FX_T( get_value, int() const );
SET_FX_T( get_value, int( std::string ) const );
luna::set_fx( ut, "get_value",
sol::resolve<int() const>( &UT_CLASS::get_value )
);
Coding Conventions
Follow Cataclysm-BN C++23 style (see AGENTS.md):
auto function_name( int param ) -> int { return param * 2; }
auto ut = luna::new_usertype<UT_CLASS>( );
luna::set_fx( ut, "method",
[]( UT_CLASS &self ) -> int { return self.value; }
);
auto result = my_struct{ .a = 1, .b = 2 };
auto values = items
| std::views::filter( []( const auto &v ) { return v.is_valid(); } )
| std::ranges::to<std::vector>();
auto my_variable = 42;
Testing Your Bindings
local obj = MyClass.new()
local result = obj:some_method()
print(obj.some_field)
local instance = MyClass.static_factory("arg")
local derived = DerivedClass.new()
derived:base_method()
Build and Verify
cmake --build --preset linux-full --target cataclysm-bn-tiles cata_test-tiles
cmake --build build --target format
./out/build/linux-full/tests/cata_test-tiles "[lua]"
Common Patterns Reference
Units (mass, volume, energy, angle)
luna::set_fx( ut, "from_gram", &units::from_gram<std::int64_t> );
luna::set_fx( ut, "to_gram", &units::to_gram<std::int64_t> );
Time (duration, time_point)
Coordinates (tripoint, point)
Troubleshooting
Issue: Linker errors about undefined references
- Fix: Include the header file containing the class implementation
Issue: luna_traits<T>::impl is false
- Fix: Add
LUNA_DOC or appropriate macro to catalua_luna_doc.h
Issue: Ambiguous function call
- Fix: Use
SET_FX_T or sol::resolve to specify exact signature
Issue: Type not copyable/movable
- Fix: Use
luna::no_constructor and provide factory functions
Issue: Method returns reference but Lua sees copy
- Fix: Consider if reference is correct, or use pointers
Files to Modify
src/catalua_luna_doc.h - Add LUNA_* macro
src/catalua_bindings_*.cpp - Implementation (choose or create)
src/catalua_bindings.h - Declare registration function
src/catalua_bindings.cpp - Call registration in reg_all_bindings()
Reference Files
- Example complex class:
src/catalua_bindings_creature.cpp (Character, Creature)
- Example with items:
src/catalua_bindings_item.cpp
- Luna system:
src/catalua_luna.h
- Utility macros:
src/catalua_bindings_utils.h
- Integration docs:
docs/en/mod/lua/explanation/lua_integration.md