-
Notifications
You must be signed in to change notification settings - Fork 0
Concepts Message Types
github-actions[bot] edited this page May 1, 2026
·
3 revisions
..-Getting-Started | ..-Getting-Started-Getting-Started | ..-Guides-Patterns | ..-Getting-Started-Visual-Guide
This guide introduces the three message categories in DxMessaging with concepts, when to use them, and practical code.
- Untargeted: global notifications anyone can listen to (e.g., world regenerated).
- Targeted: directed at one recipient (e.g., heal Player by 10).
- Broadcast: emitted from a source for anyone to observe (e.g., Enemy took 5 damage).
flowchart TD
Start([Choose Message Type])
Start --> Q1{Is it a global<br/>announcement?}
Q1 -->|Yes<br/>e.g., game paused,<br/>settings changed| Untargeted[ Use UNTARGETED<br/>Everyone listens]
Q1 -->|No| Q2{Are you commanding<br/>a specific entity?}
Q2 -->|Yes<br/>e.g., heal Player,<br/>open Chest #3| Targeted[ Use TARGETED<br/>One recipient]
Q2 -->|No| Q3{Is an entity announcing<br/>something happened?}
Q3 -->|Yes<br/>e.g., Enemy died,<br/>Chest opened| Broadcast[ Use BROADCAST<br/>Anyone can observe]
Q3 -->|No| Rethink[Rethink your<br/>message design]
classDef primary stroke-width:3px
class Untargeted primary
classDef warning stroke-width:3px
class Targeted warning
classDef success stroke-width:3px
class Broadcast success
classDef danger stroke-width:2px
class Rethink danger
classDef neutral stroke-width:2px
class Start,Q1,Q2,Q3 neutral
- Use for cross-cutting notifications: settings changed, scene loaded, world regenerated.
- Any listener can subscribe; no specific sender/recipient required.
- Define as immutable structs; prefer generic interface for zero-boxing.
using DxMessaging.Core.Messages;
using DxMessaging.Core.Attributes;
using DxMessaging.Core.Extensions;
[DxUntargetedMessage]
[DxAutoConstructor]
public readonly partial struct SceneLoaded
{
public readonly int buildIndex;
}
// Emit (bind struct to a variable)
var sceneLoaded = new SceneLoaded(UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex);
sceneLoaded.Emit();- Use for commands/events directed at one entity: Heal, EquipWeapon, OpenDoor.
- You address a specific
InstanceId(e.g., a player GameObject/component). - Ideal when only one recipient should act.
using DxMessaging.Core.Messages;
using DxMessaging.Core.Attributes;
using DxMessaging.Core.Extensions;
using UnityEngine;
[DxTargetedMessage]
[DxAutoConstructor]
public readonly partial struct Heal
{
public readonly int amount;
}
// Emit to one target (GameObject)
var heal = new Heal(10);
heal.EmitGameObjectTargeted(playerGameObject);- Use for reactionary "facts" about a specific source: TookDamage, PickedUpItem.
- Many systems can observe and react independently.
- Distinct from targeted: the source is the sender; listeners decide if they care.
using DxMessaging.Core.Messages;
using DxMessaging.Core.Attributes;
using DxMessaging.Core.Extensions;
using UnityEngine;
[DxBroadcastMessage]
[DxAutoConstructor]
public readonly partial struct TookDamage
{
public readonly int amount;
}
// Emit from a source (GameObject)
var hit = new TookDamage(5);
hit.EmitGameObjectBroadcast(enemyGameObject);Group related messages inside a container class for better organization:
using DxMessaging.Core.Attributes;
public partial class CombatEvents
{
[DxTargetedMessage]
[DxAutoConstructor]
public readonly partial struct Heal
{
public readonly int amount;
[DxOptionalParameter(false)] // Custom default value
public readonly bool showEffect;
}
[DxBroadcastMessage]
[DxAutoConstructor]
public readonly partial struct TookDamage
{
public readonly int amount;
[DxOptionalParameter(Expression = "DamageType.Physical")] // Enum default
public readonly DamageType type;
}
}
// Usage:
var heal = new CombatEvents.Heal(10, showEffect: true);
heal.EmitComponentTargeted(player);
var damage = new CombatEvents.TookDamage(5); // Uses DamageType.Physical
damage.EmitGameObjectBroadcast(enemy);- Reduces namespace pollution
- Makes message relationships clear
- Works with all message types (Untargeted, Targeted, Broadcast)
- Full source generator support
- All targeted of a type (any target):
RegisterTargetedWithoutTargeting<T>or post-process withRegisterTargetedWithoutTargetingPostProcessor<T>. - All broadcast of a type (any source):
RegisterBroadcastWithoutSource<T>or post-process withRegisterBroadcastWithoutSourcePostProcessor<T>.
using DxMessaging.Core;
using DxMessaging.Core.Messages;
// Observe every Heal regardless of target
_ = token.RegisterTargetedWithoutTargeting<Heal>(OnAnyHeal);
void OnAnyHeal(ref InstanceId target, ref Heal m) => Audit(target, m);
// Observe every TookDamage regardless of source
_ = token.RegisterBroadcastWithoutSource<TookDamage>(OnAnyTookDamage);
void OnAnyTookDamage(ref InstanceId source, ref TookDamage m) => Track(source, m);- Start with Broadcast for "X happened at Y" facts others may observe.
- Use Targeted when one specific recipient must act.
- Use Untargeted for global state changes anyone might care about.
- Keep messages small, immutable, and specific.
- Use attributes +
DxAutoConstructorfor clarity and onboarding. - Use GameObject/Component helpers (
EmitGameObject*/EmitComponent*) instead of manualInstanceIdcasts. - Organize related messages using nested types for better structure.
- Use internal visibility for implementation-only messages.
- Don't use Untargeted for per-entity commands; prefer Targeted.
- Don't overload Broadcast for commands; commands need a recipient (Targeted).
- Avoid deep inheritance trees; messages should be small, flat data.
- Don't emit from temporaries; bind structs to a variable before
Emit*.
- to ..-Getting-Started-Getting-Started -- Understand the basics first
- to ..-Getting-Started-Visual-Guide -- See the 3 types visualized
- to ..-Guides-Patterns -- Real-world examples of each type
- to Listening-Patterns -- All the ways to receive messages
- to Interceptors-And-Ordering -- Control message flow
- to ..-Getting-Started-Quick-Start -- Working example
- to Mini Combat sample -- See all 3 types in action
- Getting-Started-Overview
- Getting-Started-Getting-Started
- Getting-Started-Install
- Getting-Started-Quick-Start
- Getting-Started-Visual-Guide
- Concepts-Message-Types
- Concepts-Listening-Patterns
- Concepts-Targeting-And-Context
- Concepts-Interceptors-And-Ordering
- Guides-Patterns
- Guides-Unity-Integration
- Guides-Testing
- Guides-Diagnostics
- Guides-Advanced
- Guides-Migration-Guide
- Advanced-Emit-Shorthands
- Advanced-Message-Bus-Providers
- Advanced-Runtime-Configuration
- Advanced-String-Messages
- Reference-Reference
- Reference-Quick-Reference
- Reference-Helpers
- Reference-Faq
- Reference-Glossary
- Reference-Troubleshooting
- Reference-Compatibility
Links