Replication Overview
Summary: Project Eternal uses Unreal's standard replication with FFastArraySerializer for efficient delta replication of collections (Inventory, Map Exploration, POIs). Components replicate via SetIsReplicatedByDefault(true) with RepNotify callbacks for client-side state updates.
Table of Contents
Why This Architecture
Design Philosophy
The replication system is built around three core principles:
- Component Autonomy - Each component manages its own replication, reducing coupling and making systems modular
- Efficient Collection Sync - Large arrays (inventory, exploration) use delta serialization to minimize bandwidth
- Server Authority - All gameplay state changes originate on the server; clients receive updates through replication
When to Use Each Approach
| Scenario |
Approach |
Why |
| Simple properties (health, stamina) |
DOREPLIFETIME |
Automatic sync, minimal overhead |
| Large arrays with frequent changes |
FFastArraySerializer |
Only changed elements replicate |
| Nested UObjects (items) |
Replicated SubObjects |
Maintains object identity across network |
| Immediate client feedback |
Server RPC + NetMulticast |
Server validates, all clients see result |
Replication Flow
+------------------+ +-----------------+ +------------------+
| SERVER | | NETWORK | | CLIENT |
| (Authority) | | | | (Simulated Proxy)|
+------------------+ +-----------------+ +------------------+
| | |
| Property Changes | |
| (DOREPLIFETIME) | |
|---------------------------->|--------------------------->|
| | |
| | OnRep_ Callback Fires |
| | |
| FastArray Delta | |
| (only changed entries) | |
|---------------------------->|--------------------------->|
| | PostReplicatedAdd/Remove |
| | |
| SubObject Registration | |
| (nested UObject sync) | |
|---------------------------->|--------------------------->|
| | |
| | UI Updates via MVVM |
| | |
Component-Based Replication
Components handle their own replication setup in their constructors:
UItemContainerComponent
|
+-- SetIsReplicatedByDefault(true)
+-- bReplicateUsingRegisteredSubObjectList = true
+-- InventoryList (FInventoryFastArray)
Property Replication
Standard Pattern
Properties are registered for replication in GetLifetimeReplicatedProps. The macro DOREPLIFETIME handles basic cases, while DOREPLIFETIME_CONDITION_NOTIFY provides more control.
Replication Macros
| Macro |
Use Case |
Example |
DOREPLIFETIME |
Basic property sync |
Simple values, references |
DOREPLIFETIME_CONDITION |
Conditional sync |
Owner-only, skip owner |
DOREPLIFETIME_CONDITION_NOTIFY |
Sync with callback |
GAS attributes |
DOREPLIFETIME_WITH_PARAMS_FAST |
Push-based control |
FastArray containers |
Condition Types
| Condition |
Behavior |
COND_None |
Always replicate to all connections |
COND_OwnerOnly |
Only to owning connection (private data) |
COND_SkipOwner |
To everyone except owner (visible to others) |
COND_InitialOnly |
Only on initial replication |
FFastArraySerializer Pattern
Why FastArray?
Standard TArray replication sends the entire array when any element changes. FastArray solves this by:
- Delta Serialization - Only modified entries are sent
- Callbacks -
PostReplicatedAdd, PreReplicatedRemove, PostReplicatedChange
- Dirty Marking - Explicit control over what replicates
FastArray Architecture
+------------------------+
| FFastArraySerializer |
+------------------------+
^
| inherits
+------------------------+
| FInventoryFastArray |
| FExplorationFastArray |
| FPOIFastArray |
+------------------------+
|
| contains
+------------------------+
| FFastArraySerializerItem |
| - FInventoryEntry |
| - FExplorationEntry |
| - FMapPOIEntry |
+------------------------+
FastArray Implementations
| FastArray |
Owner Component |
Purpose |
FInventoryFastArray |
UItemContainerComponent |
Item container contents |
FExplorationFastArray |
UMapExplorationComponent |
Explored map cells |
FPOIFastArray |
UWorldPOIManagerComponent |
Points of interest |
Callback Flow
Server: InventoryList.AddEntry(Item, Index)
InventoryList.MarkItemDirty(Entry)
|
v
Network Delta Sent
|
v
Client: PostReplicatedAdd(AddedIndices)
- RegisterSubObject(Item)
- Item->SetOwningContainer(this)
Replicated SubObjects
Why SubObjects?
Items are UObjects that need to maintain identity across the network. SubObject replication ensures:
- Object Persistence - Same UObject instance on server and client
- Property Sync - Item properties replicate automatically
- Pointer Validity - References stay valid after replication
SubObject Lifecycle
+-------------+ +--------------+ +----------------+
| Add Item | --> | Register | --> | Replicate |
| to Array | | SubObject | | to Clients |
+-------------+ +--------------+ +----------------+
|
v
AddReplicatedSubObject(Item)
+-------------+ +--------------+ +----------------+
| Remove Item | --> | Unregister | --> | Remove from |
| from Array | | SubObject | | Clients |
+-------------+ +--------------+ +----------------+
|
v
RemoveReplicatedSubObject(Item)
Registration Requirements
| Condition |
Method |
| Check if ready |
IsUsingRegisteredSubObjectList() |
| Check replication state |
IsReadyForReplication() |
| Validate object |
IsValid(SubObj) |
RepNotify Patterns
Pattern Types
| Pattern |
Use Case |
Implementation |
| Simple |
Synchronization point |
Empty callback body |
| With Old Value |
Delta comparison |
GAS attributes |
| FastArray |
Collection sync |
Rebuild derived state |
| Interpolated |
Smooth corrections |
Movement, transforms |
RepNotify Flow
Server: Property = NewValue
|
v
Replication
|
v
Client: OnRep_Property() fires
|
+-- Update local state
+-- Broadcast delegates
+-- Trigger UI refresh
Common RepNotify Uses
| Component |
Property |
RepNotify Purpose |
UItemContainerComponent |
InventoryList |
Rebuild grid, broadcast change |
UEternalAttributeSet |
Health |
GAS attribute prediction |
AEternalCharacter |
ReplicatedServerPosition |
Movement interpolation |
UCombatComponent |
AvailableCombatMontages |
Sync montage data |
RPC Types
Server RPC (Client to Server)
Used for gameplay-critical operations where the server must validate and execute.
Client Request Server Validation Result
| | |
v v v
Server_SwapItems() --> Validate Items --> Execute + Replicate
--> Validate Space
--> Validate Owner
NetMulticast (Server to All Clients)
Used when all clients need immediate notification of an event.
| Reliability |
Use Case |
Example |
| Reliable |
Critical state changes |
Death, equipment changes |
| Unreliable |
Visual effects |
Hit particles, audio |
RPC Decision Matrix
| Need |
RPC Type |
Reliability |
| Client wants action |
Server RPC |
Reliable |
| All see result immediately |
NetMulticast |
Reliable |
| Visual-only feedback |
NetMulticast |
Unreliable |
| Owner-only feedback |
Client RPC |
Reliable |
Source References
Property Replication
UItemContainerComponent::GetLifetimeReplicatedProps - Source/ProjectEternal/Private/Inventory/Components/ItemContainerComponent.cpp:45
UEquipmentComponent::GetLifetimeReplicatedProps - Source/ProjectEternal/Private/EquipmentManagement/Components/EquipmentComponent.cpp:32
UEternalAttributeSet::GetLifetimeReplicatedProps - Source/ProjectEternal/Private/AbilitySystem/EternalAttributeSet.cpp:15
FastArray Implementations
FInventoryFastArray - Source/ProjectEternal/Public/Inventory/FastArray/FastArray.h:12
FExplorationFastArray - Source/ProjectEternal/Public/Automap/AutomapTypes.h:45
FPOIFastArray - Source/ProjectEternal/Public/Automap/AutomapTypes.h:78
SubObject Registration
UItemContainerComponent::AddRepSubObj - Source/ProjectEternal/Private/Inventory/Components/ItemContainerComponent.cpp:156
FInventoryFastArray::PostReplicatedAdd - Source/ProjectEternal/Private/Inventory/FastArray/FastArray.cpp:28
RepNotify Callbacks
UItemContainerComponent::OnRep_InventoryList - Source/ProjectEternal/Private/Inventory/Components/ItemContainerComponent.cpp:89
AEternalCharacter::OnRep_ReplicatedServerPosition - Source/ProjectEternal/Private/Character/EternalCharacter.cpp:234
Recent Changes
| Date |
Change |
Reason |
| - |
Initial documentation |
Document existing replication architecture |
Future Considerations
| Enhancement |
Benefit |
Complexity |
| Replication Relevancy |
Reduce bandwidth for distant actors |
Medium |
| Conditional Replication |
Owner-only private data |
Low |
| Replication Graph |
O(1) actor relevancy checks |
High |
| Property Compression |
Quantized floats for bandwidth |
Medium |