Skip to content

FAQ -- Frequently Asked Questions

Back to Index | Troubleshooting | Getting Started | Glossary


Do I need to use attributes or source generators

  • No. You can implement IUntargetedMessage<T>, ITargetedMessage<T>, or IBroadcastMessage<T> directly (recommended for structs). Attributes are optional and help tooling/source-gen.

Which message type should I use?

  • Untargeted - global notifications (any listener).
  • Targeted - commands/events for a specific recipient.
  • Broadcast - facts emitted from a source that others may observe.

How do I enforce ordering?

  • Use the priority parameter at registration; lower runs earlier. Interceptors run before handlers; post-processors run after.

Can I observe all targets/sources for a type?

  • Yes. Use RegisterTargetedWithoutTargeting<T> or RegisterBroadcastWithoutSource<T> (and their post-processor counterparts).

How do I diagnose what's happening?

My MessageAwareComponent subclass does not receive messages. What is wrong?

The most common cause is forgetting to call base.Awake() (or base.OnEnable(), base.OnDisable(), base.OnDestroy(), base.RegisterMessageHandlers()) when you override one of those methods. The framework's setup runs in those base calls; without them, your registration token is never created or your handlers never enable. The Roslyn analyzer flags this as DXMSG006. See Inheritance and base calls for the full list of guarded methods.

What happens if I register a listener inside a message handler?

  • The newly registered listener will not run for the current message emission. It will only become active starting with the next message emission.
  • This is called "snapshot semantics" -- when a message is emitted, DxMessaging takes a snapshot of all current listeners and uses that frozen list for the entire emission.
  • This applies to all listener types (handlers, interceptors, post-processors) and all message categories (Untargeted, Targeted, Broadcast).
  • This behavior prevents infinite loops and ensures predictable execution order. See Interceptors & Ordering for details and examples.

Do I need a global bus?

  • A global bus is provided (MessageHandler.MessageBus). You can also create and pass your own MessageBus instance to isolate subsystems and tests.

Is this compatible with Unity's SendMessage/UnityEvents

  • Yes. You can integrate with legacy patterns via ReflexiveMessage. Prefer DxMessaging for new code.

Why is my game retaining memory across scenes?

  • Each scene introduces new InstanceIds and sometimes new message types, which add empty slots on the bus when their handlers tear down. Idle eviction will reclaim them eventually; for deterministic cleanup call MessageHandler.TrimAll(force: true) on scene unload (or bus.Trim(force: true) for a non-global bus). See the Memory Reclamation guide for the full pattern.