How-To: Broadcast & Listen for Messages

Goal: send a one-way, struct-typed event on a gameplay-tag channel and receive it elsewhere - no references between sender and receiver. This is the approved way for plugins to fire events at each other.

Prerequisites
CrimsonCommon is enabled. Define (or pick) a USTRUCT payload and a GameplayTag channel both sides agree on. The struct can live in CrimsonCommon or in the sending plugin.

1. Broadcast

Get the subsystem off any world context and broadcast your struct on a channel tag. Anyone listening on that channel (or a parent of it) receives a copy.

Screenshot pendingImages/CrimsonCommon/howto-message-listen.png
Broadcast Message (Channel tag, wildcard payload struct) on the right; the Listen for Crimson Messages async node on the left.

2. Listen

Register a listener for the channel. In Blueprint use the async Listen for Crimson Messages node (UCrimsonAsyncAction_ListenForMessage). In C++ the member-function overload is automatically weak-object-safe. Choose ExactMatch (this channel only) or PartialMatch (this channel and any child).

cpp
// Member-function overload - safe if 'this' dies before the message arrives.
ListenerHandle = UCrimsonMessageSubsystem::Get(this).RegisterListener(
Tag_Event_Damage, this, &UMyComp::OnDamage);
void UMyComp::OnDamage(FGameplayTag Channel, const FMyDamageMessage& Msg)
{
// react to Msg.Amount
}

3. Stop listening

cpp
ListenerHandle.Unregister();
// or: UCrimsonMessageSubsystem::Get(this).UnregisterListener(ListenerHandle);
Verify
Broadcast once and confirm the listener fires; unregister and confirm it stops. PartialMatch listeners on A also receive broadcasts on A.B.
Messages are not replicated
The bus is local to one game instance. To notify remote machines, broadcast on each from a replicated event (RPC / RepNotify) - the subsystem does not cross the network.

See also

  • Concept: Decoupling Patterns - messaging as decoupling pattern #3
  • API Reference - UCrimsonMessageSubsystem, ECrimsonMessageMatch