Overview¶
Back to Index | Getting Started | Quick Start | Visual Guide
DxMessaging is a type-safe messaging system for Unity that addresses three common pain points of traditional event systems:
- Memory leaks from forgotten unsubscribes -> Automatic lifecycle management
- Tight coupling creating refactoring nightmares -> Full decoupling with no direct references
- Debugging black holes ("what fired when?") -> Built-in Inspector diagnostics
What Problems Does It Solve?¶
For Beginners: "I'm calling methods manually everywhere"¶
Traditional approaches often look like this¶
C#
public class Player : MonoBehaviour {
public HealthBar healthBar;
public AudioManager audio;
public AchievementSystem achievements;
void TakeDamage(int amount) {
health -= amount;
healthBar.UpdateHealth(health); // Manual call
audio.PlayDamageSound(); // Manual call
achievements.CheckDamage(amount); // Manual call
// Add analytics? More manual calls...
}
}
Every new system = another SerializeField + another manual call. This approach requires frequent updates as systems are added.
DxMessaging fixes this¶
C#
void TakeDamage(int amount) {
health -= amount;
var damage = new TookDamage(amount);
damage.EmitComponentBroadcast(this);
// Subscribed systems react to this message.
}
For Intermediate Devs: "I use C# events but they leak"¶
You know this pain¶
C#
void OnEnable() { GameManager.OnScoreChanged += UpdateUI; }
void OnDisable() { /* Missing this results in a memory leak: */ }
DxMessaging manages subscription lifecycle automatically, eliminating the need for manual unsubscribe - cleanup occurs when components are destroyed.
For Advanced Devs: "I need observability and control"¶
- See message history in Inspector (timestamps, payloads, call counts)
- Priority-based execution (deterministic ordering)
- Interceptors (validate/normalize before handlers)
- Global observers (track ALL instances of a message type)
- Local bus islands (isolated testing, zero global state)
What It Solves (Technical)¶
- Decoupling without references - producers/consumers never know about each other
- Predictable lifecycle - explicit tokens tied to Unity component lifecycles
- Performance - struct messages passed by-ref, designed to minimize allocations and boxing
- Observability - interceptors, post-processors, diagnostics, registration logs
- Scalable taxonomy - three message types (Untargeted/Targeted/Broadcast) cover most common messaging patterns
When to Consider DxMessaging¶
Use it when¶
- You have 3+ systems that need to communicate
- You've debugged memory leaks from forgotten unsubscribes
- You're tired of UI depending on 15 different gameplay systems
- You want to see "what fired when" without setting 50 breakpoints
- You're building for the long term (months/years, not days)
Skip it when¶
- Game jam prototype (<1 week)
- Tiny project (<1000 lines)
- Single-system communication (call the method directly)
- You need synchronous return values (DxMessaging is fire-and-forget)
Core ideas
- Message categories
- Untargeted: Global notifications (e.g., settings changed).
- Targeted: Sent to one specific target (e.g., Heal(10) to Player).
- Broadcast: Emitted from a source; anyone can observe (e.g., TookDamage from Enemy).
- Ordering: Lower priority runs earlier; same priority uses registration order.
- Pipeline: Interceptors -> Handlers -> Post-Processors, with diagnostics optionally enabled.
- Unity integration:
MessagingComponentandMessageAwareComponentmanage subscription lifecycles automatically.
Key Features¶
Global Observers: Observing All Instances¶
Traditional event systems force you to do this¶
C#
// Subscribe to each entity type separately
PlayerEvents.OnDamaged += TrackPlayerDamage;
EnemyEvents.OnDamaged += TrackEnemyDamage;
NPCEvents.OnDamaged += TrackNPCDamage;
// Add a new entity type? More subscriptions...
DxMessaging lets you do this¶
C#
// Subscribe ONCE to ALL damage, regardless of source
_ = Token.RegisterBroadcastWithoutSource<TookDamage>(
(InstanceId source, TookDamage msg) => {
Analytics.Log($"{source} took {msg.amount} damage");
}
);
Example use cases: Achievement systems, combat logs, and analytics that work with any entity - including ones added later.
Other Features¶
- Priority-based ordering - control execution flow explicitly
- Interceptor pipeline - validate/normalize messages BEFORE handlers run (one validation, all handlers protected)
- Local bus islands - isolated testing with zero global state contamination
- Low-allocation design - struct messages passed by-ref, minimizes boxing and GC pressure
- Auto-constructor generation -
[DxAutoConstructor]eliminates boilerplate while keeping type safety - Unity-first helpers -
EmitGameObjectTargeted(),EmitComponentBroadcast()feel natural - Inspector diagnostics - see message history, registrations, call counts in real-time
Related Documentation¶
Start Here¶
- -> Mental Model (10 min) - Philosophy and first principles
- -> Visual Guide (5 min) - Beginner-friendly introduction
- -> Getting Started (10 min) - Complete guide
- -> Quick Start (5 min) - Working example
Go Deeper¶
- -> Message Types - When to use Untargeted/Targeted/Broadcast
- -> Comparisons - DxMessaging vs alternatives
- -> Design & Architecture - How it works
Install & Setup¶
- -> Install - Installation guide
- -> Compatibility - Unity versions