The event system is the primary hook mechanism for Starship mods. It lets you register typed events, attach prioritised listener callbacks, and optionally cancel default engine behaviour — all from plain C or C++ without patching original game code.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/HarbourMasters/Starship/llms.txt
Use this file to discover all available pages before exploring further.
Core Types
Every piece of the event system is built on a handful of primitive types defined inport/hooks/impl/EventSystem.h.
| Type | Underlying Type | Purpose |
|---|---|---|
EventID | uint32_t | Identifies a registered event type |
ListenerID | uint32_t | Identifies a registered listener |
EventPriority | enum | Controls callback invocation order |
IEvent | struct | Base event — all event structs embed this |
EventCallback | function pointer | Signature every listener must match |
EventListener | struct | Pairs a priority with a callback |
EventPriority
Priority values
EVENT_PRIORITY_HIGH run first, followed by EVENT_PRIORITY_NORMAL, then EVENT_PRIORITY_LOW. Use a higher priority when your listener must run before others — for example, if it may cancel the event.
IEvent
Base event struct
IEvent as its first member (named event). Setting event.cancelled = true inside a listener signals cancellation; subsequent behaviour depends on which call-site macro the engine used.
EventCallback
Callback signature
IEvent* to the concrete event type to access its extra fields.
EventListener
Listener struct
API Reference
C++ code can call either the class methods via
EventSystem::Instance or the C helper functions — both compile to the same underlying logic. Mods written in C must use the EventSystem_* functions or the convenience macros below.Macros
The macros wrap the C API into a clean, type-safe interface. Prefer them over callingEventSystem_* functions directly.
Declaring and Defining Events
DEFINE_EVENT — define a new event struct
DEFINE_EVENT — define a new event struct
typedef struct { IEvent event; /* fields */ } eventName; declaration and a companion uint32_t eventName##ID variable. Use this once, in the header that owns the event.Example
DECLARE_EVENT — forward-declare an event ID
DECLARE_EVENT — forward-declare an event ID
extern uint32_t eventName##ID; so other translation units can reference the event without including the defining header. Put this in any shared header.Example
Registering Events and Listeners
REGISTER_EVENT — allocate a slot for an event
REGISTER_EVENT — allocate a slot for an event
EventSystem_RegisterEvent() and stores the result into eventType##ID. Call this once during your mod’s initialisation.Example
REGISTER_LISTENER — attach a callback
REGISTER_LISTENER — attach a callback
EventSystem_RegisterListener(eventType##ID, callback, priority). Returns a ListenerID you can hold onto if you ever need to unregister.Example
Firing Events
CALL_EVENT — fire without checking cancellation
CALL_EVENT — fire without checking cancellation
CHECK_IF_NOT_CANCELLED later if you need to inspect the result.Example
CALL_CANCELLABLE_EVENT — inline cancellation check
CALL_CANCELLABLE_EVENT — inline cancellation check
if (!cancelled) guard.Example
CALL_CANCELLABLE_RETURN_EVENT — return early if cancelled
CALL_CANCELLABLE_RETURN_EVENT — return early if cancelled
return;s from the enclosing function if any listener set cancelled = true. Convenient for guarding entire update or draw functions.Example
CHECK_IF_NOT_CANCELLED — deferred cancellation test
CHECK_IF_NOT_CANCELLED — deferred cancellation test
cancelled flag from the event struct that CALL_EVENT left on the stack. Useful when you need to do work between the call and the cancellation check.Cancellable vs Non-Cancellable Events
Not all events support cancellation. The distinction lies in how the engine fires the event:- Non-cancellable — the engine uses
CALL_EVENT. Listeners may still setcancelled = true, but the engine ignores it. - Cancellable — the engine uses
CALL_CANCELLABLE_EVENTorCALL_CANCELLABLE_RETURN_EVENT. Settingcancelled = truesuppresses default engine behaviour for that frame.
Priority Ordering
Complete Working Example
The following example hooks into the post-game-update tick — the most common integration point for per-frame mod logic.mymod.c
Include
port/hooks/Events.h with INIT_EVENT_IDS defined exactly once per mod — typically in your main .c file. All other files should include individual event headers without defining INIT_EVENT_IDS.Cancelling a Draw Call
Replace the default boost gauge
Unregistering a Listener
Teardown example