Tutorial: Networked Physics - Pawn Tutorial

@F4ll_ouT Hello, we don’t have a client authoritative physics multiplayer solution in Unreal Engine at this point.

Disabling UPrimitiveComponent.bReplicatePhysicsToAutonomousProxy will only stop the client from running physics replication for the Autonomous Proxy actor, so you don’t get corrected to the servers state.

But there is no logic that makes the server correct itself to the autnomous proxy state. You will need to write a solution that sends the autonomous proxy state to the server and apply the state there.

Issues with client authority comes with interactions in physics, imagine you and another player both jumping onto a see-saw (a tipping board which is physics simulated) you both land on it at the same time in realtime, it takes time to send states over the network though so neither of you see eachother landing at the same time.

On your screen you see yourself land on it on the right side, pushing the left side up into the air. The other player sees themself land on left side pushing the right side up into the air.

You both send your autonomous proxy positions to the server which applies your positions, but what happens to the see-saw on the server?
Which one of the two players were correct? Both can’t be correct since you will see two completely different physics states but the server is also not allowed to say any of you were incorrect?

Who owns the see-saw? If you land on it at the same time and you try to take client ownership of the see saw then it becomes a race-condition for who gets their AActor::SetOwner call first to the server. But even if one of the clients got ownership of the see-saw the other autonomous proxy interacting with that see-saw is not allowed to be corrected so it might see the see saw getting snapped up into a different state but the autonomous proxy player might then clip into the physics collider or end up under the see saw instead of following it up.

If the server is the owner of the see saw then you could use Predictive Interpolation for the see-saw but the server is not allowed to correct players. So interactions will be subject to latency which results in sluggish interactions.

Your autonomous proxy will land on the see-saw and it’s not going to be allowed to push it down more than a little bit depending on how much Predictive Interpolation (or your own physics interpolation logic) allows it to move away from the server state it replicates with. So you will land on it and push it a little bit down and you will have to wait for the server to receive your autonomous proxy state where you are clipping into the see-saw on the server forcing the server to move the see-saw down and then you need to wait for that state to arrive from the server for the see saw to move down a bit which allows you to push it down a little bit further due to leniency in Predictive Interpolation. And so on..

My recommendations with networked physics is to take it slow, step by step ensure things work with each new thing you do since if you take many steps in a row it might be hard to debug what is causing issues. So if you follow the tutorial and then add smaller things continuously ensuring things work each time and then solving the issues that pop up you will be able to make complex pawns from this.

@MBobbo , I added a callback to my code. Unfortunately, it doesn’t save you from crashing. I tried to debug and the crash occurs before calling OnPhysicsObjectUnregistered_Internal ((

…..

Everything seems to be working. It was my mistake. I forgot to add Chaos::ESimCallbackOptions::PhysicsObjectUnregister to Chaos::TSimCallbackObject

@mizarates Hello, discrete actions are hard with networked physics due to full forward prediction and complete server authority. There are a couple of things you can do to make them better but my recommendation is to have something that isn’t an instant action or not an impulse. For example a jet-pack applying a force is better than an impulse jump.

You can also have a delay so when you hit the button to jump the pawn crouches down a little before it jumps, which gives you time to send the jump input to the server and to simulated proxies which can then apply the actual jump on the correct frame but with a faster animation for the “load up”.

It’s good if you can build and design the game around the limitations of the solution if you are not able to dig in and improve the solutions for your needs.

Resimulation is not optimized yet and doesn’t scale well, it’s one of the larger goals for next year.
There is a Physics Replication LOD system in Unreal Engine already which I wrote a year ago but it’s not finished yet so it has flaws. It’s not used anywhere yet but you can test it out if you want to. It transitions replicated physics objects between the interpolated timeline (where it uses Predictive Interpolation) and the forward predicted timeline (where it uses Resimulation).

Predictive Interpolation is a cheaper physics replication mode, used in LEGO Fornite for example and handles scaling better than Resimulation does, but it’s not viable for physics-based pawns.

Enable Physics Replication LOD in Project Settings → Physics → Replication, there you have a setting to “Enabled Physics Replication LOD” along with some settings.

You then need to mark your pawn as the focal point of the LOD, you do this via the UNetworkPhysicsSettingsComponent which take a UNetworkPhysicsSettingsDataAsset. In the DataAsset there is a setting under “General Settings” called “Focal Point in Physics Replication LOD” which you enable. Put the settings component on your pawn and link the data asset to it.

There are some CVars for the LOD here p.ReplicationLOD.
If you use the debug draw CVar for the LOD you also need to enable Chaos DebugDraw: p.Chaos.DebugDraw.Enabled 1

There is no public documentation for this yet and it’s not a completed feature but it’s something I’ll work on next year. It might be hard to understand how it works but if you want to dig in the files are PhysicsReplicationLOD.h and .cpp

Hopefully by mid-end next yet I’ll have a tutorial up with this too.

1 Like

It works for me (the classic answer)
Is everything else working for you with resimulation and networking etc.?
Are you using async physics?
Do you have Enabled Physics Prediction ticked in project settings?

Are you sure that your game thread is not sending the PhysicsObject each frame or something via the AsyncInput to the physics thread?

(post deleted by author)

@MBobbo Hi. I managed to fix the crash. However, I came across a strange behavior of a physical pawn. Perhaps you can tell me When the possession of the character occurs before the physical pawn, then the Actor Relevance stops working adequately. For example, the usual situation is when the distance was exceeded, the pawn was destroyed on the proxy client. However, after the approach, the pawn does not appear on the proxy client. She disappears forever. I have debugged and found out that it is not being updated.
SrcLocation
in

bool APhysicsPawn ::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation)

In SrcLocation
the coordinates of the place where the possession was committed are received. I’ve done a lot of experiments, and this problem only occurs with the physical pawn. I also want to take the liberty of noting that if you specify a physical pawn as the default pawn, then there will be no problem. However, if you make possession from a character to a physical pawn, then the Actor Relevance will be broken.

This function “IsNetRelevantFor” will not be called with iris. I disabled iris, because according to my observations, it does not play a role in this context.