Multiplayer Guide
Quick Reference
| Goal | Setup |
|---|---|
| Zone music (forest, cave, tavern) | Place ERP_MusicVolume |
| Zone music synced between players | Enable Network Sync on the volume |
| Global music (boss fight, cutscene) | SyncComponent → SyncPushMusicLayer |
| Local stinger (pickup, UI) | AERP_StingerVolume, scope = Local Only |
| Stinger for all players | AERP_StingerVolume, scope = Everyone |
Music Volumes
Default — Local Playback
Each player triggers volumes independently when they enter. No network traffic.
Setup: Place ERP_MusicVolume in your level. Done.
Network Sync — Time-Synced Playback
Music still plays locally per player, but playback position is synchronized. A player entering 30 seconds after another hears the music at the 30-second mark.
Setup: Enable Music | Behavior → Network Sync on the volume.
Trigger Modes
| Mode | Behavior |
|---|---|
| Toggle | Enter = start, leave = stop |
| Enable | One-shot start on entry |
| Disable | One-shot stop on entry |
Actor Filter Tag — Only actors with the specified GameplayTag trigger the volume.
Stinger Volumes
Network Scope
| Scope | Behavior |
|---|---|
| Local Only | Only the entering player hears the stinger |
| Everyone | All clients hear the stinger when any player enters |
Spatialization
| Mode | Behavior |
|---|---|
| 2D (Flat) | Same volume everywhere |
| 3D (Localized) | Positioned at volume center with distance attenuation |
3D stingers remain active when the listener moves far away. The sound attenuates with distance but continues playing, so returning players hear it at the correct position.
Runtime Control
| Function | Description |
|---|---|
StopStinger() | Stop the currently playing stinger |
Example: Tavern Door Bell
- Place
AERP_StingerVolumeat the door - StingerSound → bell sound
- Network Scope →
Everyone - Spatialization →
3D (Localized) - Attenuation Start Distance →
2000.0 - Trigger Once →
false
Global Music Sync
For music that all clients should hear regardless of location.
Blueprint Helpers (Recommended)
Use the ERP Music Helper functions — they work from server or client with automatic routing:
Sync Push Music Layer (LayerName, Music, Priority, ...) ← all clients play
Sync Pop Music Layer (LayerName) ← all clients stop
Sync Clear All Layers ← stop everything
Sync Play Stinger (StingerSound, ...) ← all clients hear
Sync Stop Stinger (Handle) ← all clients stop
Tag-based variants:
Sync Push Music Layer By Tag (Tag)
Sync Pop Music Layer By Tag (Tag)
No need to get the subsystem or SyncComponent manually. No need to check authority — the helpers route the call through the network automatically.
Example: Boss Phase Music
Event "Enter Phase 2"
↓
Sync Pop Music Layer ("BossPhase1")
↓
Sync Push Music Layer ("BossPhase2")
All clients switch music. Late-joiners hear it at the correct offset.
Example: Victory Stinger
Event "Boss Defeated"
↓
Sync Clear All Layers
↓
Sync Play Stinger (VictoryFanfare)
Example: Tag-Based
Event "Enter Dungeon"
↓
Sync Push Music Layer By Tag (Music.Zone.Dungeon)
Advanced: Direct SyncComponent Access
For fine-grained control, access the SyncComponent directly (server authority required):
Get Music Subsystem → Get Or Create Sync Component → Sync Push Music Layer
C++
UERP_MusicSubsystem* MusicSys = GetGameInstance()->GetSubsystem<UERP_MusicSubsystem>();
if (UERP_MusicSyncComponent* SyncComp = MusicSys->GetOrCreateSyncComponent())
{
SyncComp->SyncPushMusicLayer(BossLayer);
FERP_EnhancedStingerParams Params;
Params.StingerSound = VictoryStinger;
FERP_StingerHandle Handle = SyncComp->SyncPlayStinger(Params);
SyncComp->SyncStopStinger(Handle);
}
SyncComponent Functions
| Function | Description |
|---|---|
SyncPushMusicLayer(Layer, Quantization) | Push a layer on all clients |
SyncPopMusicLayer(LayerName, Quantization) | Remove a layer on all clients |
SyncClearAllLayers() | Stop all synced music |
SyncPlayStinger(Params) → StingerHandle | Play a stinger on all clients |
SyncStopStinger(Handle) | Stop a synced stinger |
GetSyncedLayerNames() | Query active synced layers |
GetSyncedStingerHandles() | Query active synced stingers |
How It Works
Replication
The UERP_MusicSyncComponent lives on GameState and replicates SyncedLayers[] and SyncedStingers[] to all clients. When these arrays change, OnRep callbacks trigger local playback on each client. No audio is streamed — each client loads assets from disk.
A UERP_MusicNetRelay component is auto-created on each PlayerController to route client-initiated sync calls to the server. The Blueprint helpers use this automatically — you never need to interact with it directly.
Late-Joiner Sync
All timing uses GetServerWorldTimeSeconds(). When a client joins mid-session, it receives the current synced state and calculates the correct playback offset automatically.
Local vs Synced Layers
Local layers (from volumes, direct PushMusicLayer calls) and synced layers (from SyncComponent) coexist independently. Synced replication never affects local layers.
Background Audio
Synced music continues playing when the game window loses focus, keeping all clients in sync.
Best Practices
- Use Music Volumes for zone-based music — automatic, no network traffic
- Use Network Sync on volumes when players in the same area should hear the same beat
- Use Sync helpers (
Sync Push Music Layer, etc.) for global events — they work from server or client - Use tag-based sync (
Sync Push Music Layer By Tag) for organized projects - Test with PIE multiplayer (Number of Players: 2+)
Troubleshooting
Music doesn't play on clients
Ensure you're not calling PushMusicLayer inside a HasAuthority() block. Either call locally or use a Multicast RPC.
Synced music plays outside the volume
This is expected for SyncComponent calls — they play globally. Use ERP_MusicVolume with Network Sync for area-restricted music.
SyncComponent returns nullptr
The GameState may not exist yet. The subsystem retries automatically. Avoid calling sync functions in BeginPlay of very early actors.
Summary
| Feature | Network Traffic |
|---|---|
| Music Volumes | None |
| Music Volumes (Network Sync) | None (shared clock) |
| SyncComponent Layers | Minimal |
| Stinger Volumes (Local Only) | None |
| Stinger Volumes (Everyone) | Minimal |
| SyncComponent Stingers | Minimal |
| Audio Ducking | None |
| Volume Control | None |