Lua sections need revision: This page contains removed v5 APIs or old runtime examples. Do not use its Lua examples for current development. Start with Platform v1.
C++ Native Binding & Lua Export Guide¶
This guide describes the standard workflow for C++ engine contributors to bind internal classes, structs, and methods via Sol2 and safely export them to the CCB Lua 0.1 runtime.
1. Architectural Rules & Safety Model¶
In the CCB engine, native bindings must adhere to 3 strict rules:
1. Generation-Safe Handles:
- Raw C++ pointers (Character*, item*, monster*) must never be held indefinitely in Lua.
- Dynamic entities must be wrapped in a game_handle that verifies generation counters (runtime_generation, world_generation) upon dereference to prevent dangling pointer crashes.
2. Zero-Copy In-Memory Invocation:
- C++ and Lua interact directly through the Sol2 / Lua-C stack in memory. No intermediate JSON serialization is used.
3. 100% Contract Coverage & LuaLS Parity:
- Every exported symbol must be paired with complete LuaLS type definitions in data/lua/types/ccb_api_v5.d.lua and pass check_coverage.py.
2. Step 1: Implementing Native Bindings in C++¶
// src/catalua_ui_weather.cpp
#include "weather.h"
#include "catalua_platform_content.h"
#include <sol/sol.hpp>
namespace catalua {
sol::table get_storm_forecast(
lua_State *lua,
const game_handle &target_pos,
const int forecast_hours )
{
sol::state_view state( lua );
// Capability check
require_capability( state, "game.read", "game.weather.get_storm_forecast" );
// Native C++ engine invocation
const weather_forecast forecast = weather_manager::forecast_at( target_pos.pos(), forecast_hours );
sol::table result = state.create_table();
result["has_storm"] = forecast.has_storm;
result["intensity"] = forecast.intensity;
result["wind_speed"] = forecast.wind_speed;
result["predicted_turn"] = forecast.predicted_turn;
return result;
}
void register_weather_bindings( sol::state_view &lua ) {
sol::table weather_ns = lua["game"]["weather"].get_or_create<sol::table>();
weather_ns["get_storm_forecast"] = &get_storm_forecast;
}
} // namespace catalua
3. Step 2: Providing LuaLS Type Annotations (.d.lua)¶
In data/lua/types/ccb_api_v5.d.lua:
---@class WeatherForecast
---@field has_storm boolean Whether a storm is forecasted
---@field intensity number Storm intensity index (0.0 to 1.0)
---@field wind_speed number Forecasted wind speed in km/h
---@field predicted_turn integer Forecasted arrival turn
---Query forecasted severe weather conditions for target coordinates
---@param target_pos Tripoint Target tripoint
---@param forecast_hours integer Forecast window in hours
---@return WeatherForecast Forecast structure
function game.weather.get_storm_forecast(target_pos, forecast_hours) end
4. Step 3: Contract Generation & 100% Coverage Checks¶
Run local contract validators:
# 1. Regenerate C++ export inventory
python3 tools/lua_api/generate_ccb_inventory.py
# 2. Regenerate public contract & coverage
python3 tools/lua_api/generate_public_contract.py
# 3. Verify coverage & declarations
python3 tools/lua_api/check_coverage.py --require-complete
python3 tools/lua_api/check_luals_declarations.py
python3 -m unittest discover -s tools/lua_api -p 'test_*.py'