#
Quick Start Guide
AP Event Bus is a server-authoritative, replicated event messaging system for UE5 multiplayer. Any actor can publish a named event — identified by a Gameplay Tag — onto a bus. Any actor can listen for events by tag. No direct references required between publishers and subscribers.
Free product. No GAS dependency. 100% Blueprint accessible.
Support: discord.gg/n5HxmrkpC4
#
1. Installation
- Copy the
AfterPrimeEventBus/folder into your project'sPlugins/directory. - Open your project in UE5.
- Go to Edit → Plugins, search for "AP Event Bus", enable it, and restart the editor.
- No additional configuration required.
#
2. Recommended Setup — Global Bus on GameState
The most common pattern is a single global bus placed on the GameState, making it accessible from any actor in the world at any time.
- Open (or create) your GameState Blueprint.
- In the Components panel, click Add and search for AP_EventBus.
- Add the component — it appears as
AP_EventBusin the panel. - Set this GameState in your GameMode under Class Defaults → Game State Class.
That's all the setup required for a global bus.
#
Alternative — Per-Actor Bus
Place UAP_EventBusComponent on any individual Actor (Character, Pawn, PlayerState, etc.) to create a bus scoped to that actor. Each component instance is an independent bus — events published to one do not reach listeners on another.
#
3. Getting a Reference to the Bus
In your Character or Actor Blueprint, get a reference to the bus once in BeginPlay and store it in a variable.
Use the Get Event Bus from Game State node found under AP|EventBus|Utilities:
Timing
Add a short Delay (0.1s) before calling Get Event Bus from Game State in BeginPlay to ensure the GameState has fully replicated before access — especially important in multiplayer.
#
4. Publishing Events
Call Publish Event on your bus reference. This is the only publish node you need — it handles all client-to-server routing automatically.
Transparent Client Routing
You do not need to check authority or call different functions from client vs server. PublishEvent automatically detects if it's called on a client and routes to the server via a Server RPC. One node works from anywhere.
Use Make Event Payload (under AP|EventBus|Utilities) to construct payloads as a pure node without splitting struct pins manually.
#
5. Delivery Scopes
#
6. Listening for Events
Two complementary approaches — use both simultaneously on the same component.
#
Catch-All — OnEventReceived
Fires for every event published to the bus regardless of tag.
- Drag off your bus reference → Assign On Event Received
- Wire the generated event node to your logic
#
Per-Tag Filtering — ListenForEvent + OnListenedEventReceived
Fires only for specific tags you register. Best when an actor only cares about a subset of bus traffic.
- Call Listen for Event on the bus with the tag you want to filter on
- Bind Assign On Listened Event Received
- The bound event fires only when that specific tag is published
Call StopListeningForEvent(Tag) or StopAllListening() to remove filters at any time. StopAllListening() is called automatically in EndPlay — no manual cleanup needed on actor destruction.
Multiplayer Binding
Bind delegates on both server and client. BeginPlay fires on each machine independently so binding in BeginPlay naturally covers both. Do not gate bindings behind HasAuthority.
#
7. Late-Join Cache — Persistent Events
Some events represent state that late-joining clients should receive immediately on connect — a match phase change, a captured objective, a game state transition. Register these tags as persistent so their last payload is cached server-side and delivered to new clients automatically.
#
Setup
In your GameState BeginPlay (server only), call Register Persistent Event for each tag you want to cache:
How It Works
- Server calls
RegisterPersistentEvent(Tag)at setup - Every
PublishEventfor that tag updates the server-side cache with the latest payload - When a new client connects, their bus component automatically requests all cached events
- The client receives each cached event via
OnEventReceivedandOnListenedEventReceived— no special handling needed on the client side
#
Cache Query API
Query persistent event state directly without waiting for a delegate — useful for checking state on demand:
Server-Side Only
The cache query API is meaningful on the server. On clients the cache is empty — use OnEventReceived to react to events on clients.
#
8. Gameplay Tag Setup
AP Event Bus uses Gameplay Tags as event identifiers. No tags are shipped with the plugin — you define your own.
To add tags: Project Settings → Project → Gameplay Tags → Add New Gameplay Tag
Recommended Hierarchy
Event.GameName.EventName — for example Event.MyGame.PlayerDied, Event.MyGame.ObjectiveCaptured
This keeps your event tags organised and separate from other tag namespaces in the project.
#
9. Multiplayer Checklist
- Bus component is on the GameState (or relevant actor) and that actor replicates
- Bus reference is fetched with a
Delay (0.1s)in BeginPlay to ensure GameState is available -
PublishEventis used from all machines — no manual authority checks needed - Delegates are bound on both server and client — not gated behind
HasAuthority - Persistent events are registered in GameState BeginPlay on the server before any events fire
- Demo tags registered in your project's Gameplay Tags config before use
#
10. What the Plugin Does Not Do
Current Limitations
- No persistent state across level loads or game sessions — all cache is transient
- No listener priority ordering — planned for v1.1
- No wildcard or parent-tag event matching — planned for v1.1
- No timed or delayed events — planned for v1.2
#
Next Steps
- API Reference — complete class, function, delegate, enum, and struct documentation
- Changelog — version history and roadmap
AfterPrime Systems — Building the Gameplay Foundation