Scripting API
Events
The event system lets scripts communicate without direct references. Scripts can emit named events with optional payloads, and other scripts can subscribe to receive them.
Functions
subscribe_event
Register a callback for a named event.
uint64_t subscribe_event(ScriptContext* ctx,
const char* event_name,
void (*callback)(void* user_data,
uint64_t entity_high,
uint64_t entity_low,
const char* payload),
void* user_data);
| Parameter | Type | Description |
|---|---|---|
event_name | const char* | Event name to listen for (e.g., "player_death", "item_collected") |
callback | function pointer | Function invoked when event fires |
user_data | void* | Opaque pointer passed to callback (can be nullptr) |
Returns a subscription handle (0 = failed). Use this handle to unsubscribe later.
emit_event
Broadcast an event to all subscribers.
void emit_event(ScriptContext* ctx,
const char* event_name,
uint64_t entity_high,
uint64_t entity_low,
const char* json_payload);
| Parameter | Type | Description |
|---|---|---|
event_name | const char* | Event name |
entity_high | uint64_t | High 64 bits of source EntityHandle (or 0 for broadcast) |
entity_low | uint64_t | Low 64 bits of source EntityHandle (or 0 for broadcast) |
json_payload | const char* | JSON-encoded payload string (can be nullptr, treated as "{}") |
unsubscribe_event
Remove a subscription.
bool unsubscribe_event(ScriptContext* ctx,
const char* event_name,
uint64_t handle);
Returns true if the subscription was found and removed.
Example: Damage System
DamageDealer.cpp — emits damage events:
void OnUpdate(ScriptContext* ctx) {
if (ctx->is_key_pressed(ctx, 70)) { // F key
ctx->emit_event(ctx, "deal_damage", 0, 0,
"{\"amount\": 25, \"type\": \"fire\"}");
}
}
HealthSystem.cpp — subscribes and reacts:
static float health = 100.0f;
static uint64_t sub_handle = 0;
void on_damage(void* user_data, uint64_t eh, uint64_t el,
const char* payload) {
// payload = "{\"amount\": 25, \"type\": \"fire\"}"
health -= 25.0f; // In production, parse the JSON payload
if (health <= 0) {
// Handle death
}
}
void OnStart(ScriptContext* ctx) {
sub_handle = ctx->subscribe_event(ctx, "deal_damage",
on_damage, nullptr);
}
void OnDestroy(ScriptContext* ctx) {
if (sub_handle) {
ctx->unsubscribe_event(ctx, "deal_damage", sub_handle);
}
}
Example: Game State Events
// Emit when player collects a coin
ctx->emit_event(ctx, "coin_collected", 0, 0,
"{\"value\": 10}");
// Emit when level completes
ctx->emit_event(ctx, "level_complete", 0, 0,
"{\"level\": 3, \"time\": 45.2}");
// Emit entity-specific event
// Pass entity handle split into high/low 64-bit parts
ctx->emit_event(ctx, "entity_hit", entity_high, entity_low,
"{\"damage\": 50}");