Problems with interpolation
Hey,
We''re using reasonably simple client-side interpolation that just uses the velocity to move objects around between net updates. This works absolutely fine and smooth and dandy if you''re running the client on the same machine as the server, but if the client is on a different machine (over LAN) the interpolation decides it sucks and movement becomes rather jerky.
The interpolation is still working (the car still moves between net updates) but the car jerks noticeably a few times a second. It is odd because exactly the same process is used to deliver messages from the server and interpolate them wether the client is running on the same machine as the server or not.
No packets are being dropped, and they aren''t being received out of order. We are sending updates about 20 times a second. The only thing i can think is that messages aren''t being received exactly 0.05 seconds (approx) apart as they may be on the client-server machine, but i wouldn''t have thought this should cause such problems.
Has anyone had this sort of trouble and come up with a solution? Or, is there perhaps another reason people could think of??
Thanks,
CYer, Blitz
you could try to also send rotational velocity with your updates
also instead of forcing the cars on a newly received update to their new positions might be wrong (in the sense of reducing popping). so when you get a new packet you know in ~0.05 seconds there will be a new one so get the position your car will be then and interpolate to there from the curent position (on the client not the updated one, hope you understand this
)
one warning though:
never tried this myself as networking has yet to come for my engine
also instead of forcing the cars on a newly received update to their new positions might be wrong (in the sense of reducing popping). so when you get a new packet you know in ~0.05 seconds there will be a new one so get the position your car will be then and interpolate to there from the curent position (on the client not the updated one, hope you understand this
![](wink.gif)
one warning though:
never tried this myself as networking has yet to come for my engine
![](smile.gif)
http://mitglied.lycos.de/lousyphreak/
Are you using TCP or UDP? Apparently there''s some funny algorithm in TCP (forget what it''s called) which attempts to combine small packets for improved efficiency at the cost of a slightly increased latency. There''s some way to turn this off, but again I''m not sure of the details.
(Sorry for the lack of information in this post -- maybe someone else will be able to fill in the details if it''s applicable)
(Sorry for the lack of information in this post -- maybe someone else will be able to fill in the details if it''s applicable)
We''re using usp, and we already use predictive interpolation for both position and rotation.
Any other ideas?![](smile.gif)
Like i said, the biggest annoyance is that it works perfect if the client and server are on the same machine, but not on different machines, even though they essentially receive exactly the same data and operate on it the same way! It drives me to madness![](smile.gif)
CYer, Blitz
Any other ideas?
![](smile.gif)
Like i said, the biggest annoyance is that it works perfect if the client and server are on the same machine, but not on different machines, even though they essentially receive exactly the same data and operate on it the same way! It drives me to madness
![](smile.gif)
CYer, Blitz
It sounds like your problem is time related. Since the client and server run great on the same system, perhaps it is because both apps are sync'ed on the same system clock. Try processing your state loop in 100 ms intervals, one interval ahead of real (current) time. That way you have time to send data to the clients and by the time the data is needed, it has already arrived and is accurate to the moment. 100 ms is slow for a lan, but you should understand the general idea.
One other thing to try is to build in a 'tolerance' or margin of error in your interpolation. If you don't update the cars position to that of the server unless the interpolation completely failed and is off by more than X, then you can still have a fairly accurate representation of the server, while avoiding the jerks.
The nagle algorithm. Probably not the problem here though, as his interpolation should cover any latency (which should be nil on the lan anyways).
gl
[edited by - fingh on October 27, 2003 8:20:51 PM]
One other thing to try is to build in a 'tolerance' or margin of error in your interpolation. If you don't update the cars position to that of the server unless the interpolation completely failed and is off by more than X, then you can still have a fairly accurate representation of the server, while avoiding the jerks.
quote:
Apparently there's some funny algorithm in TCP (forget what it's called) which attempts to combine small packets for improved efficiency at the cost of a slightly increased latency
The nagle algorithm. Probably not the problem here though, as his interpolation should cover any latency (which should be nil on the lan anyways).
gl
[edited by - fingh on October 27, 2003 8:20:51 PM]
I thought i might just post the algorithm i''m using, in case theres something fundamentally wrong that i''m not seeing ![](smile.gif)
This is just for the movement...
I''ve looked over this nuemrous times and it seems correct...but occasionally my brain just refuses to see whats in front of me![](smile.gif)
CYer, Blitz
![](smile.gif)
This is just for the movement...
// Pos and Vel are the current position and velocity received// from the server// PosErrSqr is the square of the "tolerance" that we allow// the object to move from it''s true position// TimeInterval and InvInterval are (approx) the time between// network updates (eg 0.1 and 10 for 10 updates/second)// CurPos is the current position of the object as determined by// interpolation// PosVel is the current velocity as determined by interpolationvoid Merpolator::SetPositional( const Vector3 &Pos, const Vector3 &Vel ){ // check if we are outside the error if ( ((Pos - CurPos).MagnitudeSquared()) > PosErrSqr ) { // snap to the true position/velocity PosVel = Vel; CurPos = Pos; } else { // Predict the target position Vector3 TargetPos; TargetPos = Pos + ((Vel) * TimeInterval); // Modify the current velocity so that // it is relative to CurPos and TargetPos (rather than Pos and TargetPos) // The velocity is equivalent to the distance between CurPos and TargetPos // over the time interval. PosVel = ((TargetPos - CurPos) * InvInterval); } }// called every framevoid Merpolator::Update( float dt ){ // // Positional // // use the velocity to interpolate a position between the current position // and the target position CurPos += PosVel * dt;}
I''ve looked over this nuemrous times and it seems correct...but occasionally my brain just refuses to see whats in front of me
![](smile.gif)
CYer, Blitz
quote:
Original post by Blitz_Krieg
We are sending updates about 20 times a second. The only thing i can think is that messages aren''t being received exactly 0.05 seconds (approx) apart as they may be on the client-server machine, but i wouldn''t have thought this should cause such problems.
Why not measure this and find out? If the messages come in very uneven bursts then your interpolation would have to be more intelligent to compensate for this.
[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]
October 28, 2003 12:44 PM
There are many issues which could be affecting your interperlation. From inconsistent packet reception times, unsynchornize clocks, to the brittleness of your interperlation algorihtim, etc..
In non-lan situations packets will be recived in irregular bursts. Thats just a given fact. I''ve never had that happen on a lan though. So, unless your injecting some non-derterministic latency overhead into the pings, which you should check, the root of the problem is in your clock sync or lack of it.
To determine if this is the issue try this lock step technique. Send a tick packet every 1 sec to your client. When the client recives it it sets its current time tick to that value. Of course it keeps updating in between. Eventually the clocks will become synchronize over a lan, since the latency is so low, proably in ~5 secs. This wont work for the internet due to the unpredicable and higher latencies.
Once the clocks are synchornize, tag your movement packets with a timestamp and only update them when you are within not only spatial but temporal bounds. If your are beyond either of those, you can pop the client into position.
This i feel should solve your poping issue. Also you''ll need to develope some robust timming synchronization algorithims, if you want to synchronize movement over the internet.
Good Luck!
-ddn
In non-lan situations packets will be recived in irregular bursts. Thats just a given fact. I''ve never had that happen on a lan though. So, unless your injecting some non-derterministic latency overhead into the pings, which you should check, the root of the problem is in your clock sync or lack of it.
To determine if this is the issue try this lock step technique. Send a tick packet every 1 sec to your client. When the client recives it it sets its current time tick to that value. Of course it keeps updating in between. Eventually the clocks will become synchronize over a lan, since the latency is so low, proably in ~5 secs. This wont work for the internet due to the unpredicable and higher latencies.
Once the clocks are synchornize, tag your movement packets with a timestamp and only update them when you are within not only spatial but temporal bounds. If your are beyond either of those, you can pop the client into position.
This i feel should solve your poping issue. Also you''ll need to develope some robust timming synchronization algorithims, if you want to synchronize movement over the internet.
Good Luck!
-ddn
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement