Event System
The event system is how plugins communicate without direct dependencies. When something happens in one plugin (item collected, ability used, quest completed), it publishes an event. Any other plugin can subscribe to that event and react.
ISparkEvent Interface
Every event implements ISparkEvent:
public interface ISparkEvent
{
string EventType { get; }
float Timestamp { get; }
string Source { get; }
int Priority { get; }
bool CanBeCancelled { get; }
}EventType
A string identifier for the event type (e.g., "ItemPickedUp").
Timestamp
When the event was created (Time.time).
Source
Optional string identifying what caused the event.
Priority
Event priority. Higher priority events may be processed differently by some systems.
CanBeCancelled
Whether handlers can consume (stop) this event.
Creating Custom Events
Inherit from SparkEventBase, which provides default implementations for most properties:
SparkEventBase automatically sets Timestamp to Time.time at construction. Priority defaults to 0 and CanBeCancelled defaults to false.
To make an event cancellable, also implement IConsumableEvent:
Publishing Events
Use SparkEventBus.Publish<T>() for immediate, synchronous dispatch:
All subscribed handlers run synchronously in priority order before Publish returns.
For batch processing, queue events and process them together:
Queuing is useful when multiple state changes happen as part of a single action and you want all events to fire after all changes are applied.
Subscribing to Events
Implement ISparkEventHandler<T>:
Register the handler with the event bus:
Unsubscribe when no longer needed:
Always unsubscribe handlers when the subscribing object is destroyed or disabled. Failing to do so can cause memory leaks and errors.
Handler Priority and Ordering
Handlers execute in descending priority order. Higher HandlerPriority values run first:
This lets you create handlers that can validate or block an event before lower-priority handlers process it.
Event Consumption
When an event implements IConsumableEvent, a handler can stop propagation by returning true from Handle(). Subsequent lower-priority handlers will not receive the event.
For non-consumable events, the return value of Handle() is ignored. All handlers always run.
Type Matching
The event bus supports polymorphic subscriptions. If you subscribe to a base class or interface, your handler receives all events of that type and its subtypes:
String-Based Event Listeners
For simpler use cases (often in UI bindings), Spark provides StringBasedEventListener. This lets you subscribe to events by their EventType string rather than by C# type. This is primarily used by the editor and UI systems.
Built-in Event Types
Spark and its plugins publish many events. Here are some common categories:
UI Events (from Core):
UIPanelShownEvent,UIPanelHiddenEventFirstUIPanelOpenedEvent,AllUIPanelsClosedEventEscapeKeyPressedEventShowEventMessageEvent
Character Events (from Character plugin):
Character creation and loading events
Game Settings Events (from GameSettings plugin):
GameSettingsLoadedEventGameSettingsUIOpenedEvent,GameSettingsUIClosedEventKeybindChangedEvent
Each optional plugin adds its own events. See the Plugin API Reference section for complete event listings per plugin.
Error Handling
The event bus catches and logs exceptions thrown by handlers. A failing handler does not prevent other handlers from receiving the event. Exceptions are logged with full stack traces for debugging.
Best Practices
Keep events immutable. Set all properties in the constructor and expose them as read-only.
Use descriptive
EventTypestrings that match the class name (e.g.,"MountSummoned"forMountSummonedEvent).Always pair
SubscribewithUnsubscribeto prevent leaks.Keep handlers lightweight. If a handler needs to do heavy work, queue it for the next frame.
Use event consumption sparingly. Most events should reach all handlers.
Prefer specific event types over base class subscriptions. Specific types are faster and clearer.
Include a
Sourcestring in events to help with debugging and filtering.
Last updated
Was this helpful?
