Networked Physics with PhysX

Is this for networked physics for player controlled objects only or can some of this be applied to get smoother networked physics for objects in general (that are not player controlled)?

I’m trying to make a robust replicated actor pickup and currently I just use the default unreal actor replication for position and create a physics handle on said actor (turning off net replication on grab and turning on net replication on release). This works well except for circumstances where trying to grab a fast moving actor client side with lag leads to a grab occurring on the server but not client side due to the greater discrepancy in the actors position in client vs server.

I need the replicated position to be more smooth I figure? Anyone have thoughts on this or if the discussion here is the right info for me to look at?

@Nonlin

It’s depend on your game design and gameplay.

About the pick up, you can use lag compensation.

A roughly lag compensation implementation.

  • Server keeps history buffer.

  • Client send pickup RPC with sync server timestamp and its position on client.

  • Server use timestamp to search history buffer and start validating pickup on client. If validating is correct, let that client pick the object regardless of its current state.

  • Server can use round trip time instead of sync server timestamp from RPC but it’s still prone to hacking as much as sync server timestamp.

  • This technique prop and cons

    • prop: picker almost doesn’t experience lag. If they pick and doesn’t cheat, they always pick the object.

    • cons: For the case with high latency picker,The picked object may move back in the past position or high latency picker steal it from other picker.

  • To illustrate problem, see Rocket League video above around 29.00min.

For sync server timestamp.

  • Client send client timestamp to server.

  • Server reply back with server timestamp and received client timestamp.

  • Client filter duplicate and late reply using client timestamp.

  • Client use client timestamp from replay and its current timestamp to calculate round trip time. Offset this round trip time to server timestamp.

For smoothing physic visual.

  • Separate visual and rigidbody. Rigidbody simulate physic. Visual doesn’t simulate physics.

  • My current set up is that rigidbody is root component and visual is its child You can try other setup too. It’s up to you.

  • When receive replication.

    • Snap rigidbody but don’t snap visual.

    • There are many approaches how you smooth visual to rigidbody.

      • First approach, Decay the different by percentage between visual and rigidbody. You may need different decay value depending on situation. See State Synchronization | Gaffer On Games for more information.

      • Second approach, Use velocity blending. Visual simulates as if it’s old rigidbody before getting update. The result will be blend with rigidbody. Visual blend two thing, its current velocity and current position. See Dead reckoning - Wikipedia for more information. This technique is published by Murphy, Curtiss. Believable Dead Reckoning for Networked Games. Published in Game Engine Gems 2

      • Third approach, Use beizer curve. I haven’t looked into this yet.


On other note, I’m testing with sleep rigidbody with non-zero velocity. PhysX still wakes rigidbody anyway.
Need to modify PhysX code. It’s just changing the flag.
The problem it’s that I’m not sure how Unreal compile PhysX and integrate to engine. It seem to manage third party party using CMake.

I’m not sure if we can approximate this and ignore restitution which use to resolve both rigidbody’s velocity in collision.

I’ve been trawling the internet for days regarding replicating ball physics for a multiplayer golf game I’m trying to put together and this is the first thread that is helping me to progress. Thanx for sharing your knowledge guys, it is extremely valuable. Do you think this lag compensation with server buffer is the way to go for a golf game which will result in the ball transform being identical across clients when the ball comes to a rest?

I need accuracy but it doesn’t have to be immediate as only one client triggers the shot and then everyone else can view the shot even after a small delay.

I’m pretty new to networking and this is the biggest hurdle I’ve come up against + I’m solely using blueprints

Any links to examples or feedback regarding how to approach this would be GREATLY appreciated. Thanks in advance.

@LiquidJoy

Actually, I’m a newbie here. I come from Unity and start learning Network Synchronization using Unreal Engine.

I think what you need is client prediction and reconciliation.

To do that, you need to keep history for your golf ball. I probably only keep history of delta time.
I don’t think you need to fixed timestep.
When the hit happen, you send RPC to server with client timestamp.
Server update the golf and send correction back marking with client timestamp + simulation time on server.
When correction from server come in, you put it in history buffer and start re-simulate physic.

You will need following API: http://docs.nvidia.com/gameworks/con…2f3d2168c2aff5
Unfortunately, I don’t think this is available in Blueprint.
You can get PxScene through UWorld->GetPhysicsScene()GetPhysicsScene(EPhysicsSceneType::PST_Sync)](https://api.unrealengine.com/INT/API/Runtime/Engine/Engine/EPhysicsSceneType/index.html)

Be careful about Physic event such as collision. When you simulate using PxScene, event will be put in FPhysScene. If you want to manually dispatch event you can call FPhysScene.DispatchPhysNotifications_AssumesLocked() . Otherwise this is fired in ETickingGroup::TG_EndPhysics.

I have a working rewind/replay system working. However, I’m still having trouble with the smoothing.

@BlueMan What does each of the colours represent?
Also, I’m trying to follow your explanation of how you do the smoothing.
As I understood, when you’re going to apply the correction, you store the current transform and velocities, transfer the actor to a different physics scene, snap hard the actor to the transform sent from the server, play all the moves, and when it ends, you put the actor back to the stored transform, calculate the error and add a percentage of the offset to that position. Is that right?

@BlueMan I actually found what the colors meant. Sorry, I searched it before but didn’t find it, now rereading all of this again I found it.
Another issue related with smoothing: I store the transform before setting the server transform and replaying moves. After replay, I set back to the stored transform, calculate the error offset between position at the end of replay and the stored transform position. I then set the position to be the stored transform position + error offset * percentage based on the desync. Is that similar to what you described here:

I think this is an important thread with good information. I would like to add that I got bone replication working quite nicely across the network using the technique of rewinding the physics, and replicating the server’s version of the bone state to everyone.

One tip is when you are applying the BoneTransforms on the client you receive from the server, ensure you use ETeleportType::None. The other types just got jitter for me. IE:

SetBodyTransform(FVector NewLoc, ETeleportType::None);

Note that setting bone transforms at runtime is only exposed to C++ right now.

Also, you don’t necessarily need to update the entire hierarchy of bones, just the most important structural ones.

For example, you probably have no need to replicate the individual fingers and toes of a physics ragdoll. Just replicate the root, one or two spine bones, the head, the hands, and the ankles.
That drastically reduces the amount of data to send.

You can also only send data that changed since last update, and you can compress the data too.
Right now I am able to send 17 bones 20 times per second on a mobile device with good results.

Here is a great video on the topic from one of the Rocket League devs: