Rewind & replay would become very expensive very quickly when you try to use it with a large number of objects
I find myself then confused as to how other games & engines do it, with the exception of Source Engine which has deterministic physics.
Rocket League uses UE3 and the Bullet Physics Engine, though itās relatively small scale in terms of its physics simulation.
Astroneer is UE4 based and has loads of multiplayer physics.
Crackdown 3 uses UE4 and has a massive amount of multiplayer physics. I understand they are using some cloud based magic for some of the physics, but not all of it. Have we got any speculation on how they are keeping physics states in sync between clients?
Short answer is that they donāt, but itās good enough for us not to notice most of the time. You only ever replay physics for the local object that the client controls. Other objects just receive transform and velocity updates, and the objects are smoothed between those updates. You can use Velocity and remote client input to do a bit of extrapolation which helps seal the deal as well.
In the case of Crackdown, they probably wrote their own very simple Physics solver based on a syncronised seed, but I donāt know.
You could add it to any physics object but it would get very expensive very quickly in terms of CPU time and bandwidth. Even with only your main vehicle using rewind/replay it takes a lot of your bandwidth but constant stream of updates is important for it work properly.
Btw I finished my client side prediction component and it is working better than I expected, only nightmare left is collision with dynamic objects :rolleyes:
But what about other objects that the client interacts with. Lets say a player pushes on a barrel, in a default implementation the barrel (a simulated object thatās receiving old location updates from the server) would jitter against the player. You wouldnāt be able to do simple velocity/location extrapolation either should there be a wall or other object in front of the barrel that would collide with it and prevent it from moving, right?
Thatās correct, which is why for the most part collision between two dynamic objects over the network is an unsolvable problem. Even Ubisoft havenāt cracked it yet, thereās still a lot of research to do:
http://www.gdcvault.com/play/1024597/Replicating-Chaos-Vehicle-Replication-in
Elhoussine linked me to this on Twitter. They take some interesting approaches. They use P2P, but funnily enough it looks like S2C works better for this.
BlueMan: Thanks, I think I just have to patiently tweak values until it looks good. But before that Iāll do some research on how to minimize the error between the simulations to not rely on smoothing as much as I do at the moment.
How big are the errors you have to smooth out? Iām interested in how far you tweaked the actual system before you started smoothing out the remaining differences.
That gave me some ideas how to handle dynamic collisions⦠:rolleyes:
That vehicle you see in the video is around 7 meters in length because I messed some things on import and went with it. In this case max smoothing kicks in when the error is around 1 to 1.5 meters but with normal sized vehicles it would be around 0.5 meters. Without the smoothing you can see a small amount of snapping when vehicle changes direction very fast, for example collisions, rolls, jumpsā¦
Be interesting to see how you handle it for sure, what you have right now would fullfill my needs though
I wish I had more time to spend on this
@blue man
Hey so in your client prediction videos what do the different colored meshes represent? Thanks
Hey, green - position from the server, red - old position from the client, blue - current predicted position
So if blue is the current predicted position, what does the actual vehicle represent? Its ahead of the predicted position?
The actual vehicle is a result of smoothing. It seems like it is ahead but that is because those debug things are not updated every tick.
Are you using the same model for smoothing as the exponential smoothing in CharacterMovementComponent? Thatās what Iām trying to use but it still reacts to the occasional update mismatch jitter (even with very slow interp time) and I donāt know if its the smoothing or something else Iām experiencing. Also thanks for replying. Your work looks great so far.
If MaxSmoothNetUpdateDist is set too low, then if you get a big correction you wonāt get smoothing, itāll snap.
The defaults for Character movement are fine because human pawns move slowly. You have to adjust the smoothing tolerance values to compensate for the speed at which your object moves. Smoothing is supposed to take place over short distances to eliminate small amounts of jitter.
Iām not actually using a max dist. Experiencing this jitter with a slower interpretation in low ping. But itās not like bad jitter. Itās like a hiccup every second or so, and it happens when the server update and the client update mismatch a frame (no server update, server update, no update, update, no update, update, no update, no update, update - two frames in a row where we didnāt get an update from the server). Also I should note in using fix time stamp if you didnāt see my earlier posts. And Iām not doing rewind replay because Iām not doing any client prediction yet. Trying to figure out why it doesnāt look smooth in a no lag, no prediction scenario.
Iāve submit a pull request for activate simulation fixed delta and enhanced determinism directly in the project settings:
Iām working on rewind / replay algorithm, but Iāve a problem on simulation.
Iāve created a new World (as we know) that initialize automatically the PhysX scene which Iāll use for rewind / replay process.
After moving the PxActors from the main scene to the new scene, is executed this code that should execute the simulation 10 times:
for (int32 a = 0; a < 10; ++a) {
RRWorld->SetupPhysicsTickFunctions(1.f/60);
RRWorld->GetPhysicsScene()->StartFrame();
RRWorld->GetPhysicsScene()->WaitPhysScenes();
RRWorld->GetPhysicsScene()->EndFrame(nullptr);
}
The problem is on that line RRWorld->GetPhysicsScene()->WaitPhysScenes(); for some reason the execution stop forever. Thereās no crash the executions is blocked.
Blu man, how do you execute the simulation?
Do you talked about calling the function PXScene::simulate, So you skip the FPhysScene simulation?
There is something that Iām missing?
Iām calling simulate function on PxScene and right after that I call fetch function. Also Iām not creating a new scene with UWorld but you need to have a separate UWorld if you want to trace in your scene. A new PxScene also gets created when you initialize FPhysScene and you can set in your new UWorld to use your scene.
I donāt know why but Iām getting this error:
Exception thrown at 0x00007FFFE85C72E7 (PhysX3PROFILE_x64.dll) in UE4Editor.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
At this line: PScene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, DynamicActors.GetData(), DynamicActorsNum);
Here Iām taking only the Dynamic actors for a test.
Did you do in this way?
PxScene* PScene = GetWorld()->GetPhysicsScene()->GetPhysXScene(PST_Sync);
const PxU32 DynamicActorsNum = PScene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
TArray<PxActor*> DynamicActors;
DynamicActors.AddUninitialized(DynamicActorsNum);
PScene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, DynamicActors.GetData(), DynamicActorsNum);
FPhysScene* PS = new FPhysScene();
PxScene* RRPScene = PS->GetPhysXScene(PST_Sync);
PScene->removeActors(DynamicActors.GetData(), DynamicActorsNum);
RRPScene->addActors(DynamicActors.GetData(), DynamicActorsNum);
for (int32 a = 0; a < 2; ++a) {
RRPScene->simulate(1.f / 60.f);
RRPScene->fetchResults(true);
}
RRPScene->removeActors(DynamicActors.GetData(), DynamicActorsNum);
PScene->addActors(DynamicActors.GetData(), DynamicActorsNum);
delete PS;
PS = nullptr;