Source code is currently a complete mess, I have to rewrite it. It currently heavily depends on my vehicle plugin so I would need to strip down any code related to my plugin and leave force and position replication before I can share the source code (it is also replicating suspension and engine properties).
Yeap, I know that haha, but without lag, whether you one window focused or the other, the client doesnât move aloneâŚ
So, I printed the delta time, and if I focus the client window, the delta time printed is around 0.008, but when I focus the server one it starts printing 0.01 something, and sometimes it even reaches 0.02.
I tried clamping DeltaTime everywhere I used it, between 0.0f and 0.009f, and it did nothing, same behaviour as always.
Really donât know how to move on from this
I guess I just have to keep trying, try a different approach, I donât knowâŚ
Also, donât know if it is important, but if I comment the ServerMove method call, the client one doesnât fall, but obviously its proxy on the server side doesnât ever moveâŚ
I managed to make this work. Had to rewrite the code myself but it is working, and it syncs well.
Two main problems now: when there are move replays, I get input lag somehow⌠It gets more noticeable if I call the Net PktLag command with 150ms or moreâŚ
Also, when I call simulate on the physx scene, right after, if Iâd get the UpdatedPrimitive location, it should be different then it was before, right? Because I call it, but it only changes location on PostPhysics TickâŚ
Any idea how to solve this?
EDIT: The input lag part, I think I already know what it is.
I have implemented the rewind and replay system. I have a mesh component serving as UpdatedPrimitive (simulating physics), and another mesh component serving as the visual part (not simulating physics), which is interpolated with the UpdatedPrimitive positions, for smoothing.
Even though the system syncs pretty well, even with lag, I have a somewhat big problem:
- After the first replay, on the client side it seems that the physics become a tiny bit crazy, because after it, when I leave the UpdatedPrimitive at rest, it tries to go down really slowly (even though it has code to counteract gravity), and when it reaches the threshold of difference between server position and client position it corrects with rewind and replay, and starts falling down, gradually losing speed, and seems to reach a stand still, but instead it reaches the threshold again and, there it goes, corrected once again.
Iâm assuming the physics goes crazy after the replay, because, when the game starts, it is at a stand still and it doesnât fall. It only does it after the first replay. And for the replay, I hard set the UpdatedPrimitiveâs Location, Rotation, Linear Velocity and Angular Velocity, which Iâve read that it might not be great for the behaviour of the physics engine. I hard set it with the server state, and then proceed to replay the moves with the stored inputs (by calling the movement code with the input, and subsequently calling simulate function from PhysX). My movement code uses UE4 AddForce and AddTorque functions.
So, I would like to ask you if you could you tell me how you are setting the server correction on the client? How do you make the UpdatedPrimitive take the server location and rotation, and then replay inputs, without making physics go crazy?
Could my problem be of hard setting those values and then using AddForce and AddTorque on the normal movement code?
Hope you can help me.
Hey guys, Iâm looking to replicate pawnâs ragdoll over the network, am I in the right place for that or is this something else/more?
This is something else, but replicating Ragdoll can be done the same way as normal replicated movement. You will however have to replicate bone positions for the whole skeleton, which is extremely expensive. Thereâs also no easy way to smooth it, so it will appear jittery on clients as the simulations diverge.
My advice is, donât replicate ragdollâs.
Thanks for the advice. Just to be clear, you advise against it because of how tricky it is for poor results, yes?
Now I donât mean to hijack this thread but on this point, would it be better to just replicate the ragdolls general position but not have it be bone to bone accurate? Would something like that be acceptable? Also would it be more helpful (if possible) to only have a few bones go ragdoll and replicate only a few bones positions (maybe like hands, hip, and feet)?
Also as a side note not expecting a direct answer on this but Source Engine seems to have no issues doing this, what about Unreal Engine is making this so tricky that the Epic hasnât even touched this?
Yeah you can do replication just of the position of the object (just keep replicated movement on when in ragdoll mode).
It might be that sourceâs physics sim is deterministic - whereas PhysX isnât unfortunately.
Oh I thought replicate movement would do just the capsule not the mesh of the ragdoll? Or are you saying replicate movement on for the mesh itself?
I do think deterministic ragdoll replication is overly complicated (doable but is not worth the effort) - try not to create games which has features that critically depend on the ragdollâŚ
Ragdoll can be replicated but they may not appear the same across the playersâ computers in multiplayer scene. Thus they should be accessories or eye-candies of the game
so on a side note, I actually think I need to look into what this thread is actually about. Aside from moving ragdolls I also need to implement replicating physics objects that a player can throw. I take it this is actually what this thread is about?
Iâm looking at the github link I believe is related to this thread https://github.com/TheJamsh/UE4-Networked-PhysX-Component .
Any tips for me as I get started? Does this work well?
In case youâve used the repo of Jamesh, could you create a Pull Request so your updates can be incorporated into the github repo?
There is a major logic issue with my movement component on GitHub that needs to be addressed, in that the Server is re-simulating clients with too much Delta and that Timestamp Verification is all wrong.
Line 304 in** NTGame_MovementComponent.cpp:**
[TABLE="class: highlight tab-size js-file-line-container"]
// Update Delta Time, given the last received client timestamp
const float AccelDelta = ServerData->GetServerMoveDeltaTime(MoveTimeStamp);
This is a problem, because the server will always simulate with way too much delta. I forgot that the simulation is still running on the Server in between updates for that player, and need to workaround that somehow.
No telling when Iâll have time to dig in unfortunately. Probably not until I need to use it for a projectâŚ
Iâve updated the GitHub Readme.md - I donât want people to use this in shipping games.
Your code and the ideas mentioned in this thread are a good head start into the topic. However after some basic tests it seems I canât rely on physics for replication position as well as collision between player controlled pawns. The position updates have a lot of jitter and the position of the pawn does not change.
Someone made (client authoritative) player interaction with physics in Unity: https://forum.unity.com/threads/succâŚg-unet.458027/
However the interaction is well defined:
So, I start looking into this.
My plan is to sync by physic sub-step tick instead of using time stamp or Delta Time.
The problem is that Unreal sub-step tick into separate thread.
I need to know thread timeline and when it synchronize back to game thread.
Iâm not sure at which point game thread receives replication call back.
I also look into PhysXâs immediate mode.
This can be useful if I want to replay small-subset of physics body or fast-forward projectile such as rocket.
Nvidia open source their PhysX on github you can get invite by register as Nvidia developer and agree to their license.
In PhysXâs Immediate mode snippets, The API is very complicate.
You need to compute a lot of intermediate data and allocate aligned memory for caching.
The snippets is also very slow because it brute forces computing every possible rigid-body pair.
Iâm going to experiment putting rigidbody to sleep.
http://docs.nvidia.com/gameworks/conâŚ999aad04f27c28
Then restore velocity without waking rigidbody.
http://docs.nvidia.com/gameworks/conâŚ104ad7f0f30c05
If this works, I will let you guys know.
Itâs possible to invoke a function in Game Thread from another thread, quite easy to do; but I donât know if that would be ideal to do every frame.
First of all, physics substeps actually run in the main thread since UE 4.13 (itâs still ran in a task).
Also syncing things in substeps themselves will not make any difference vs Tick other than it just creates more overhead for no actual gain. Iâll explain this a little to tell why that is so:
- physics substeps are ran immediately one next to other, thereâs no measurable time between two substeps in realtime, they are literally ran in series without any delay between them
- UE4 netcode is only synced on Tick anyway
So in the nutshell you get new physics data at the start of the Tick (as physics is ran first) and you send network events on the end of the Tick (as thatâs at the end of Tick updates). Also since your last substep will have most recent physics data in it, thereâs literally zero reason to try to send previous physics steps data at this time as that data is already outdated, you only have use for the most recent data.
edit-> I might have misunderstood the intention, but it doesnât really change much as long as you use stock ue4 physics. Your last substep will be in sync with Tick as thatâs how the ue4 substepping works, if you use fixed timesteps on physics using custom engine, this will change and then youâll actually benefit from knowing the actual timestamp of the physics step.
After taking a look at PhysSubstepTask.cpp again, Itâs just like youâve said physic sub-step run in GameThread.
Seem like this document is outdated â https://docs.unrealengine.com/en-us/âŚcs/Substepping
Iâm going to modify the source code to be fixed timestep instead of semi-fixed timestep.
Iâm not planning to fix visual noise from partial timestep yet.
I probably takes the same approach as Glenn Fielderâs, render late by one timestep instead of vary partial timestep.
By fixing physic-step, I can ensures the same amount of applying input. Index data in replay buffer and saved move buffer using physic tick. Thatâs what I mean syncing by physic sub-step.
I probably need to experiment more how to handle variance latency and packet loss.
If I donât fix timestep, My other option is to used PhysXâs Immediate Mode which is very complicate.
In Immediate Mode, You need to determine rigid-body pair yourself. So, You can determine contact point and which physics actor you want to simulate.
Itâs just like you re-implement spatial system in PhysX.
In PhysXâs Immediate Mode Snippet project, I just switch from brute force rigid-body pair method to PhxScene->simulate and I get performance boost.
Their brute force method actually performs Broadphase Detection using AABB but itâs still very slow comparing to PhxScene->simulate.
Last part of this talk covered networked physics:
Thank, this confirms my approach.
For short summary.
- They fixed timestep.
- By fixing timestep, They can index history buffer and input buffer using physic tick count.
- Client and Server has their own physic tick count. They exchange it during replication. This help locate in history buffer.
- Their method is server authoritative with client prediction for both car and ball. So, the car can hit the ball with precision. Client doesnât predict other player car. So, Hit with the car can still create discrepancy.
- Client send input array to server to handle packet loss.
- To handle jitter/latency variance, They wait a few physic ticks before consuming input buffer.
- They use method call downsteam to handle too long or too short input buffer.
-
If Serverâs input buffer is too short, Server consume 1 input for more than one physics tick.
-
If Serverâs input buffer is too long, Server consume more than 1 input per physics tick.
- They recommend using upsteam, which Overwatch is using, instead of downsteam. This technique is available on GDCValut: âOverwatchâ Gameplay Architecture and Netcode.
-
If Serverâs input buffer is too short, Server tells client to run faster.
-
If Serverâs input buffer is too long, Server tells client to run slower.
-
I assume that server tells all client . Can we do this using dilation and change upper limit of framerate?