Skip to main content
Version: 1.3.1

Oceanology NextGen - Replication & Multiplayer

🌐 Multiplayer
🔄 Push-Based
🎮 Server Authority

Configure Oceanology NextGen for multiplayer projects with server-authoritative replication for vessels, swimming, and water interactions.


Prerequisites

RequirementDetails
EngineUE5.x (latest release)
PluginOceanology NextGen installed and configured
SceneOcean actor + Oceanology Water Volume
NetworkingBasic understanding of UE5 replication (Actors, RPCs, Authority)
How Replication Works

Oceanology uses Push-Based replication for optimal network performance. Instead of polling all properties each frame, the system only sends data when properties actually change. This is handled via MARK_PROPERTY_DIRTY internally, reducing bandwidth usage significantly in large multiplayer sessions.


Architecture Overview

Oceanology's multiplayer architecture follows a server-authoritative model:

Client Input (Keyboard/Mouse)

Server RPC (Client → Server)

Server Validates & Applies Changes

Push-Based Replication (Server → All Clients)

OnRep Callbacks on Clients (visual updates, effects)

Replicated Components

ComponentRoleReplicated Properties
OceanInteractorComponentBase water detectionWater reference, Volume reference, EnteredWaterVolume
OceanBuoyancyComponentVessel floating physicsFlow spline, flow speed, spline width, force multiplier
OceanSwimmingComponentCharacter swimming30+ properties including swim state, controls, drowning
OceanologyUnderwaterComponentUnderwater effectsFog, distortion, volumetric, bubbles settings
OceanologyWaterParentWater body config20+ visual properties (caustics, foam, surface, etc.)

Setting Up Vessels for Multiplayer

Vessels require specific Actor settings for replication to function. Missing any of these causes the most common multiplayer issues.

1. Enable Actor Replication

Select your vessel Blueprint actor (e.g., BP_FishingBoat_BoxCollision). In the Details panel, locate the Replication category.

Required Settings:

ParameterValueDescription
ReplicatesCritical. The actor must be marked as replicated for any networking to work.
Replicate MovementCritical. Enables position and rotation synchronization across clients.

For StaticMeshActor vessels, there is an additional requirement:

ParameterValueDescription
Static Mesh Replicate MovementCritical for StaticMeshActors only. Without this, movement replication is silently ignored.
Common Pitfall

The plugin runs a VerifySetup() check that validates these flags. If you see warnings in the Output Log about replication, check these three settings first. This is the most frequent cause of multiplayer issues with vessels.

:::

2. Configure Physics Replication

In the root component's Physics category, configure the network physics settings.

Required Physics Network Settings:

ParameterValueDescription
Replicate Physics to Autonomous ProxySends physics state to the owning client. Required for smooth local prediction.

How Physics Replication Works:

The server runs the authoritative physics simulation. Buoyancy forces, wave sampling, and pontoon calculations all happen on the server. The resulting position, rotation, and velocity are then replicated to all clients.

Clients receive the replicated transform and interpolate smoothly between updates. This ensures all players see the same vessel position regardless of their local wave calculations.

3. Verify setup with the built-in validator

The OceanBuoyancy component includes a VerifySetup button in the Details panel under the Buoyancy category.

Click VerifySetup to check for:

  • ✅ Actor has bReplicates = true
  • ✅ Actor has bReplicateMovement = true
  • ✅ StaticMeshActors have bStaticMeshReplicateMovement = true
  • ✅ Physics is properly configured

Any failures will appear as warnings in the Output Log with clear descriptions of what needs to be fixed.


Skeletal Mesh Vessels & Physics Jitter

The Problem

When a vessel with physics simulation (Static or Skeletal Mesh) uses buoyancy in multiplayer, UE5's physics engine runs on all roles — server and clients. This creates a conflict:

  1. The server calculates buoyancy forces and pushes the vessel up against gravity
  2. On clients, the buoyancy tick does not run (server-authoritative), but the physics engine still applies gravity locally
  3. Between server position updates, gravity pulls the mesh down on clients
  4. When the server correction arrives, the mesh snaps back up → visible jitter

This effect gets worse over time ("run-off") because damping values are calculated per-tick on the server but not on clients, causing physics state to diverge progressively.

Solution: bDisableClientPhysicsSimulation

The OceanBuoyancyComponent includes a property called bDisableClientPhysicsSimulation (enabled by default since v1.2.6) that resolves this by disabling local physics simulation on non-authority clients. The vessel position is fully controlled by server replication.

When to disable this property

Only set bDisableClientPhysicsSimulation = false if you have custom client-side logic that requires local physics simulation on the vessel (e.g., procedural visual effects that depend on real-time physics state). For 99% of multiplayer vessels, keep this enabled.

For buoyant vessels, configure these values on the vessel Actor:

PropertyMinimumRecommendedDescription
NetUpdateFrequency2030Server updates per second. With PredictiveInterpolation, 30Hz provides smooth results equivalent to 60Hz without interpolation.
MinNetUpdateFrequency1015Minimum update rate during slow movement.
Replicate MovementRequired for position synchronization.
bDisableClientPhysicsSimulation- (default)Prevents client gravity from fighting server corrections.
VerifySetup Warnings

Starting in v1.2.6, VerifySetup() checks NetUpdateFrequency and MinNetUpdateFrequency for replicated actors. If you see warnings about low update frequency, increase these values in the actor's Replication settings.

PredictiveInterpolation (v1.3.0)

Starting in v1.3.0, the OceanBuoyancyComponent includes PredictiveInterpolation — a temporal interpolation system that smooths vessel movement on clients using a buffer of recent server states.

How It Works:

Server sends position update (30Hz)

Client stores in state buffer (timestamped)

Each client frame: CubicInterp between two bracketing states

Smooth, frame-accurate position without jitter

Key Design Decisions:

DecisionRationale
CubicInterp over LerpFMath::CubicInterp uses server velocities as tangents, producing curves that respect real acceleration/deceleration. Lerp produces straight-line segments that feel robotic.
No double smoothingInterpolation already produces frame-accurate positions. Adding secondary easing (VInterpTo) on top causes micro-jumps when the interpolation pair changes.
Override PostNetReceiveOverrides PostNetReceiveLocationAndRotation() and PostNetReceiveVelocity() to prevent UE5 from snapping to raw server positions, which competes with manual interpolation.
ETeleportType::TeleportPhysicsUses TeleportPhysics for SetActorLocationAndRotation to avoid physics overhead on clients where simulation is disabled.

InterpolationBackTime:

The interpolation delay must be at least 3x the server send interval:

NetUpdateFrequencySend IntervalInterpolationBackTime
20 Hz50 ms0.15s
30 Hz33 ms0.10s (recommended)
60 Hz16 ms0.05s
30Hz = Optimal for Vessels

With PredictiveInterpolation using CubicInterp, 30Hz NetUpdateFrequency provides the same visual smoothness as 60Hz with linear interpolation — at half the bandwidth cost. This is the recommended setting for buoyant vessels.


Swimming Replication

Swimming uses a combination of Server RPCs and NetMulticast RPCs for responsive multiplayer gameplay.

RPC Flow

Player presses Swim key

Client calls Server_SwimFast(true) [Server RPC]

Server validates: HasAuthority() check

Server updates: SwimFast = true

Server marks property dirty (push-based)

All clients receive replicated SwimFast

Server calls NetMulticast_SwimFast() [Visual sync]

All clients play swim animation/effects

Server RPCs (Client → Server)

These are called by the owning client to request state changes:

RPCPurpose
Server_SurfaceLockedSwimmingToggle surface-locked swimming mode
Server_SwimFastToggle fast swimming
Server_SwimUpOrDownVertical swimming input
Server_LookUpVertical look axis
Server_MoveForwardBackwardForward/backward movement input
Server_MoveLeftRightLateral movement input

All Server RPCs are marked as Unreliable for performance, since swimming input is sent every frame and occasional packet loss is acceptable.

Replicated Swimming State

These properties are automatically synchronized to all clients:

PropertyTypeDescription
EnteredWaterbool (OnRep)Player has entered a water body
Swimmingbool (OnRep)Player is actively swimming
SubmergedboolPlayer is fully underwater
WaterWalkbool (OnRep)Player is walking on water surface
SwimFastboolSprint swimming active
UnderwaterTimeCounterint32 (OnRep)Time spent underwater (for breath system)
DrowningTimeCounterint32 (OnRep)Drowning timer
DrownedToDeathbool (OnRep)Player has drowned

Properties marked (OnRep) trigger callback functions on clients when they change, allowing visual effects, UI updates, and gameplay responses to stay synchronized.


Buoyancy Replication

The OceanBuoyancyComponent replicates flow control properties for river and current-based movement.

Replicated Properties

PropertyDefaultDescription
FlowControlSplinenullptrSpline component defining the flow path
FlowControlSpeed100.0Speed along the flow spline
UnscaledSplineWidth75.0Width of the flow influence area
CharacterMovementForceMultiplier1.0Force applied to characters in flow

Authority Control

All buoyancy property changes require server authority. Attempting to modify these from a client will be silently ignored:

// Internal behavior:
void SetFlowControlSpeed(float InSpeed)
{
if (!GetOwner()->HasAuthority()) return; // Ignored on clients

FlowControlSpeed = InSpeed;
// Marked dirty → pushed to all clients
}

This means flow control changes (river currents, water flow paths) must be driven by server-side logic, such as Blueprints running on the server or gameplay events triggered with authority.


Water Body Replication

The water actor itself (OceanologyWaterParent) replicates 20+ visual configuration properties including:

  • Surface scattering and caustics settings
  • Refraction and horizon correction
  • Foam and procedural settings
  • RVT (Runtime Virtual Texture) configuration
  • Fluid simulation and wetness parameters
  • Flipbook animation settings

This ensures all clients see identical water appearance. When you change water properties at runtime through Blueprints, the changes automatically propagate to all connected clients.


Standalone Game & Dedicated Server (v1.3.0)

Automatic Support

Starting in v1.3.0, multiplayer buoyancy works correctly in Standalone Game, Dedicated Server, and Packaged Builds without additional configuration. No changes to your Blueprints or settings are required.

PIE vs Standalone Game

Understanding the difference is important for debugging multiplayer issues:

ModeServer TypeRenderingWave Solver
PIE (Play As Client)ListenServer (same process)✅ Active✅ Ticks normally
Standalone GameDedicatedServer (separate process)❌ None⚠️ May not tick
Packaged BuildDedicatedServer (separate binary)❌ None⚠️ May not tick

On a dedicated server without rendering, the OceanologyManager may not exist, which means the wave solver's GameTimeInSeconds never updates. In v1.3.0, the wave solver automatically falls back to GetWorld()->GetTimeSeconds() when this occurs, ensuring wave phases oscillate correctly.

Testing Multiplayer

Always test your buoyancy setup in Standalone Game mode in addition to PIE:

  1. PIE (Play As Client) — Quick iteration, but hides dedicated server issues.
  2. Standalone Game — Launches separate processes, reveals real multiplayer behavior.
  3. Packaged Build — Final verification before shipping.

If buoyancy works in PIE but not in Standalone Game on versions prior to v1.3.0, update the plugin.


Important Notes

Events Are NOT Replicated

The following events fire only on the local machine and are NOT replicated by design:

  • OnEnteredWater (OceanBuoyancyComponent)
  • OnExitedWater (OceanBuoyancyComponent)

If you need to respond to these events on all clients, you must implement your own replication logic using RPCs or replicated variables in your game code.

Deterministic Waves

Oceanology's wave calculations are deterministic. Given the same time and position, all clients compute identical wave heights independently. This means the water surface itself does not need to be replicated per-frame. Each client runs the same wave math locally, ensuring visual consistency without network overhead.


Troubleshooting

ProblemLikely CauseSolution
Vessel doesn't move on clientsbReplicates disabledEnable Replicates on the actor
Vessel position desyncsbReplicateMovement disabledEnable Replicate Movement on the actor
StaticMesh vessel is stuck on clientsMissing static mesh flagEnable Static Mesh Replicate Movement
Swimming doesn't syncOceanSwimmingComponent missingEnsure the component is attached to the character
Swim animations don't play on othersNetMulticast not reaching clientsVerify the character actor has Replicates enabled
Vessel jitters on clientsClient-side gravity fighting server correctionsEnsure bDisableClientPhysicsSimulation is enabled on the OceanBuoyancyComponent, and increase NetUpdateFrequency to 25+
Vessel jitter gets worse over time ("run-off")Physics state diverging between server and clientEnable bDisableClientPhysicsSimulation (default in v1.2.6). See Skeletal Mesh Vessels
Flow control changes ignored on clientAuthority check blockingEnsure flow changes are made on the server
Water looks different per clientWater actor not replicatingEnsure the water actor has Replicates enabled
OnEnteredWater not firing on clientsBy design (not replicated)Implement custom RPC for cross-client notification
High bandwidth usageToo many replicated actorsReduce Net Update Frequency for distant vessels
Vessel sinks in Standalone GameWave time frozen at 0 on dedicated serverUpdate to v1.3.0 — automatic time fallback fix
Buoyancy works in PIE but not StandaloneOverlap events or wave solver not activatingUpdate to v1.3.0 — includes fallback timer and time fix
Skeletal mesh vessel jittersClient physics conflicting with server stateEnable bDisableClientPhysicsSimulation and use NetUpdateFrequency 30 with PredictiveInterpolation

Performance Tips

TipDescription
Net Update FrequencyLower this value for vessels far from gameplay action. Default is fine for player-controlled boats.
Relevancy DistanceSet Net Cull Distance on vessel actors to stop replicating them when too far from any player.
Buoyancy Update IntervalOn clients, buoyancy calculations are cosmetic. Consider a higher update interval for non-authority vessels.
Deterministic WavesWaves are computed locally on each client. No wave data is sent over the network.
Push-Based SystemProperties only send updates when they change. Static vessels on calm water consume near-zero bandwidth.

Summary

In this guide, you learned how to:

  1. Enable actor replication - Configure the three critical replication flags on vessel actors.

  2. Configure physics replication - Set up physics state synchronization for smooth multiplayer.

  3. Validate setup - Use the built-in VerifySetup tool to catch configuration errors.

  4. Understand swimming replication - Server RPCs, NetMulticast, and replicated swim state.

  5. Configure buoyancy replication - Flow control and authority-based property updates.

  6. Handle water body replication - Automatic visual synchronization across clients.

  7. Troubleshoot common issues - Diagnose and fix the most frequent multiplayer problems.

  8. Use PredictiveInterpolation - Leverage temporal CubicInterp for smooth vessel movement at 30Hz.

  9. Support Standalone Game - Understand automatic fixes for dedicated server wave time and overlap activation.

With proper replication configured, your multiplayer project will have synchronized vessels, swimming characters, and consistent water behavior across all connected clients — including Standalone Game and Dedicated Server modes.