Physics Replication
How Forecast Works
Forecast is Fusion's physics-prediction mode. Plain replicated properties update discretely — each packet snaps the remote value to the authoritative one, and Replicated Properties covers when to add smoothing in gameplay code. Physics bodies cannot tolerate that approach: they move continuously under forces, and a snap every few network ticks looks like teleport-and-rubber-band. Forecast replaces the snap with extrapolation plus continuous correction.
The owner periodically sends an FFusionBodyState snapshot containing position, rotation as a quaternion, linear velocity, angular velocity, and the server frame it was captured on. Between snapshots, remote clients extrapolate forward from the most recent snapshot via FusionPhysicsReplication::ComputeExtrapolatedSnapshot — applying gravity (per the gravity-forecast setting) and integrating velocity — and nudge the local Chaos body toward the predicted target each physics tick. The extrapolation window is bounded by MaxExtrapolationTime; if a new snapshot does not arrive within that window the body freezes at the last predicted state rather than drifting indefinitely.
Enabling and Disabling Forecast
bForecastPhysicsEnabled on UFusionActorComponent is the master switch. It defaults to true. When false, the actor falls back to plain transform replication — the same path as a non-physics actor — and the smoothing/extrapolation pipeline is bypassed.
The component only attaches a UFusionPhysicsReplicationComponent when the root primitive is actually simulating physics. If Simulate Physics is disabled on the root, forecast is silently disabled too — there is nothing for forecast to predict. Re-enable physics on the root to bring forecast back.
C++
AMyKinematicActor::AMyKinematicActor()
{
FusionActorComponent = CreateDefaultSubobject<UFusionActorComponent>(TEXT("Fusion"));
FusionActorComponent->bForecastPhysicsEnabled = false; // fall back to plain transform replication
}
Leave forecast on for any rigid body the game wants smoothed across the network. Turn it off for kinematic actors driven directly by gameplay code through Ownership transfers — those want plain transform replication.
Supported Actor Types
Any actor whose root component is a UPrimitiveComponent with IsSimulatingPhysics() returning true is eligible for forecast. The check lives in UFusionActorComponent::CheckPhysicsReplication and runs once at attach time.
Forecast applies to the root primitive only. Non-root simulated primitives — a USkeletalMeshComponent parented under a non-physics scene root, or extra physics bodies attached deeper in the component tree — are not forecast-replicated. If forecast must apply to a specific body, promote it to the actor's root.
C++
APhysicsCrate::APhysicsCrate()
{
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
RootComponent = Mesh;
Mesh->SetSimulatePhysics(true);
FusionActorComponent = CreateDefaultSubobject<UFusionActorComponent>(TEXT("Fusion"));
// UFusionPhysicsReplicationComponent is attached automatically at runtime.
}
Error Correction Modes
EFusionPhysicsCorrection selects how the remote body is nudged toward the predicted target each physics tick.
| Mode | How correction is applied | Relevant knobs | Recommended use |
|---|---|---|---|
Velocity (default) |
Adds a corrective velocity to converge toward the target | LinearVelCorrectionMul, AngularVelCorrectionMul |
Default for most rigid bodies — smooth, no overshoot |
PositionRotation |
Lerps the body's transform toward the target | PositionCorrectionLerp, RotationCorrectionLerp |
Bodies where transform fidelity matters more than physical realism |
SpringDamping |
Applies a spring-damper force/torque toward the target | Spring, Damper |
Snappier convergence, accepts some overshoot |
C++
FusionActorComponent->ErrorCorrectionType = EFusionPhysicsCorrection::SpringDamping;
Velocity is the recommended starting point and the project-wide default. Switch to SpringDamping only when overshoot is acceptable in exchange for snappier convergence — typically vehicles or fast-moving props where lag-induced visual stretch is worse than a small bounce on arrival.
Tuning Knobs
Every tuning knob lives in two places. The project-wide default sits on UFusionOnlineSubsystemSettings and can be edited under Project Settings > Fusion. The per-actor override sits on the UFusionActorComponent itself in the Fusion | Forecast Physics category, paired with a matching Override* toggle that decides whether the per-actor value or the project default is used.
| Knob | Default | Raise to | Lower to |
|---|---|---|---|
LinearVelCorrectionMul |
4.0 | Converge linear position faster (more aggressive) | Reduce velocity-correction jitter on noisy networks |
AngularVelCorrectionMul |
1.0 | Converge rotation faster | Reduce rotational jitter |
PositionCorrectionLerp |
0.15 | Snappier position lerp | Smoother (slower) position lerp |
RotationCorrectionLerp |
0.15 | Snappier rotation lerp | Smoother rotation lerp |
Spring |
75 | Stiffer spring, faster convergence with possible overshoot | Softer spring, more lag tolerance |
Damper |
2 | More damping, less overshoot | Less damping, springier feel |
MaxLinearError |
0 (no cap) | Allow larger position divergence before forced re-sync | Force re-sync sooner on large drift |
MaxAngularError |
0 (no cap) | Allow larger rotation divergence | Force re-sync sooner |
MaxExtrapolationTime |
0.3 s | Allow longer extrapolation under heavy lag | Freeze sooner when no updates arrive |
MaxSpawnExtrapolationTime |
0.05 s | Extrapolate further on first spawn | Tighter spawn behaviour |
Tune at project scope first. Per-actor overrides are for the exceptional case where a specific actor class — a vehicle, a heavy boss, a delicate prop — needs different physics behaviour than the project default. Resist scattering overrides across many actor classes; they get hard to maintain.
Gravity Forecast
EFusionGravityForecast decides whether gravity is folded into the extrapolation pass on remote clients. Apply always folds gravity in. None never does. Auto applies gravity only when the remote body has a downward velocity component — the practical "is this thing falling?" heuristic.
The project-wide default is Auto on UFusionOnlineSubsystemSettings::GravityForecast. Override per actor via UFusionActorComponent::GravityForecast with the OverrideGravityForecast toggle enabled.
Choose None for zero-gravity environments or buoyant objects where gravity should not be applied to the prediction. Choose Apply for predictable falling props that always behave under gravity (crates, debris). Stick with Auto for mixed scenes where the same object class can be in flight, on the ground, or floating depending on context.
Collision Handling
On a hit, UFusionPhysicsReplicationComponent::OnHitCallback registers the collision and pauses correction. For ImpactStartCorrectionTime seconds after impact, no correction is applied — the local physics solver is trusted to handle the collision response. Then correction ramps back over ImpactCorrectionTimeComplete seconds. This avoids the "rubber-band on collision" artifact where the remote prediction overrides the local hit response.
For intentional snaps, the TeleportKey field on FFusionBodyState and FFusionReplicatedPhysicsTarget lets the owner force an instant transform change on remotes, skipping smoothing entirely. TeleportKey is bumped automatically by OnTransformUpdated when an ETeleportType::TeleportPhysics move is detected, so calling SetActorLocation with ETeleportType::TeleportPhysics on the owner is enough — no manual key management is needed.
Rely on the impact window to avoid the classic rubber-band-on-collision artifact. If a teleport on the owner still produces a smooth slide on remotes instead of an instant snap, confirm the move used ETeleportType::TeleportPhysics — the default ETeleportType::None is interpreted as a continuous move and gets smoothed like any other transform change.
Chaos Physics Integration
Fusion installs its replicator by registering a FusionPhysicsReplicationFactory in the engine's IPhysicsReplicationFactory slot at module startup. The factory's CreatePhysicsReplication returns the Fusion implementation, which becomes the replicator the engine asks for on each physics scene.
FusionPhysicsReplication implements the IPhysicsReplication interface, ticks each physics step, and holds an FPhysScene_Chaos* to read solver state and apply forces directly on Chaos bodies. The integration is at the solver level, not at the actor level — which is why forecast can run at physics frequency rather than tick frequency.
Chaos Physics is required. The replicator caches an FPhysScene_Chaos* and applies forces directly on Chaos bodies. PhysX-only builds are not supported by Fusion physics forecast. Unreal 5.x uses Chaos by default, so this is rarely an issue in practice — but a project that has explicitly switched back to PhysX cannot use forecast.