EventManager - markvaaz/ScarletCore GitHub Wiki
EventManager
is a static, centralized event system for ScarletCore that allows mods and systems to subscribe to, listen for, and react to a wide variety of game events. It provides a unified interface for handling player connections, chat, deaths, damage, unit spawns, war events, and more, with safe invocation and subscriber management.
Overview
using ScarletCore.Events;
// Subscribe to a player connection event
EventManager.OnUserConnected += (sender, args) => {
Log.Info($"Player connected: {args.PlayerData.CharacterName}");
};
// Subscribe to chat messages
EventManager.OnChatMessage += (sender, args) => {
Log.Info($"Chat: {args.PlayerData.CharacterName}: {args.Message}");
};
// Unsubscribe when no longer needed
EventManager.OnUserConnected -= MyHandler;
Features
- Subscribe to a wide range of game events (chat, connection, death, spawn, war, etc.)
- Safe event invocation with error handling
- Access to event arguments for context and control
- Query subscriber counts for each event
- Clear all subscribers for full reset (use with caution)
Event Categories & List
System Events
OnInitialize
— ScarletCore initialization
Chat Events
OnChatMessage
— Chat message sent
User Connection Events
OnUserConnected
— User connectedOnUserDisconnected
— User disconnectedOnUserKicked
— User kickedOnUserBanned
— User banned
Death Events
OnAnyDeath
— Any entity deathOnOtherDeath
— Unfiltered deathsOnPlayerDeath
— Player deathsOnVBloodDeath
— V Blood unit deathsOnServantDeath
— Servant deaths
Unit Spawn Events
OnUnitSpawn
— Units spawned
Damage Events
OnDealDamage
— Damage dealt
War Events
OnWarEventsStarted
— War events startedOnWarEventsEnded
— War events ended
Player Downed Events
OnPlayerDowned
— Player/vampire downed
Event Subscription Example
// Listen for player deaths
EventManager.OnPlayerDeath += (sender, args) => {
foreach (var death in args.Deaths) {
Log.Info($"Player died: {death.PlayerName}");
}
};
// Listen for unit spawns
EventManager.OnUnitSpawn += (sender, args) => {
Log.Info($"Units spawned: {args.UnitEntities.Count}");
};
Event Invocation (For Mod Developers)
Events are invoked internally by ScarletCore patches and systems. Each event has a corresponding Invoke...
method (e.g., InvokeUserConnected
, InvokeChatMessage
) that safely triggers the event and passes relevant arguments. These methods are not intended to be called directly by mods.
Subscriber Management
You can query the number of subscribers for each event:
var count = EventManager.UserConnectedSubscriberCount;
To clear all subscribers (for debugging or full reset):
EventManager.ClearAllSubscribers();
Warning: Clearing all subscribers will remove all event listeners for all mods and systems.
Event Argument Types
Each event provides a strongly-typed argument class with relevant context, such as:
PlayerData
for player eventsChatMessageEventArgs
for chatDeathEventArgs
for deathsDamageEventArgs
for damageUnitSpawnEventArgs
for spawns- ...and more
Refer to the Events/
folder for details on each argument type.
Usage Examples
Listen for chat messages and cancel them
EventManager.OnChatMessage += (sender, args) => {
if (args.Message.Contains("forbidden")) {
args.Cancel = true;
Log.Info("Blocked forbidden chat message.");
}
};
Listen for war events
EventManager.OnWarEventsStarted += (sender, args) => {
Log.Info($"War started: {args.WarEvents.Count} events");
};
EventManager.OnWarEventsEnded += (sender, args) => {
Log.Info("All war events ended.");
};
Using method handlers (with correct parameter types)
You can also use named methods instead of lambdas for event handlers. When doing so, your method signature must match the event's expected parameters.
Note: The
sender
parameter in all event handlers is the instance of the ScarletCore patch or system that detected and raised the event (for example,ChatMessageSystem
,ServerBootstrapSystem
,DeathEventListenerSystem
, etc). This allows you to access additional context or methods from the system that triggered the event if needed.
Example: Method handler for OnUserConnected
void OnUserConnectedHandler(object sender, UserConnectedEventArgs args) {
// sender is the ServerBootstrapSystem instance that detected the connection
Log.Info($"User connected: {args.PlayerData.CharacterName}");
}
// Subscribe
EventManager.OnUserConnected += OnUserConnectedHandler;
// Unsubscribe
EventManager.OnUserConnected -= OnUserConnectedHandler;
Example: Method handler for OnChatMessage
void OnChatMessageHandler(object sender, ChatMessageEventArgs args) {
// sender is the ChatMessageSystem instance that detected the chat
if (args.Message.Contains("forbidden")) {
args.Cancel = true;
Log.Info("Blocked forbidden chat message.");
}
}
EventManager.OnChatMessage += OnChatMessageHandler;
Example: Method handler for OnPlayerDeath
void OnPlayerDeathHandler(object sender, DeathEventArgs args) {
// sender is the DeathEventListenerSystem instance that detected the death
foreach (var death in args.Deaths) {
Log.Info($"Player died: {death.PlayerName}");
}
}
EventManager.OnPlayerDeath += OnPlayerDeathHandler;
Important Notes
- Events are invoked on the main thread and should not block for long periods.
- Always unsubscribe when your handler is no longer needed to avoid memory leaks.
- Do not call
Invoke...
methods directly unless you are extending ScarletCore internals. - Use event arguments to access context and, where supported, to cancel or modify behavior.
When to Use EventManager
Use EventManager
when you need to:
- React to game events in a decoupled, modular way
- Build mods that listen for player actions, deaths, chat, or world changes
- Integrate with other ScarletCore systems via events
Tip: For custom or mod-specific events, consider using
CustomEventManager
.