Jump to content
  • Advertisement
Sign in to follow this  
vhxonline

Verifying movement speed server side

This topic is 1114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am having problems with verifying the movement speed server side in my 2D game, and am looking for direction the best way to fix this.

 

Right now I have it so the client can move freely, and will periodically send updates to the server on where it's at using a coordinate system (roughly 5 times every second and on direction change). The client sends the position x, y (floats, since I go by pixels and needed to calculate movement speed correctly) and dt of the time it took to reach that position. I do this by getting the current time minus the time I last sent an update (dt). I take the times the server sends and calculate the speed based on that.
 
I also have an estimated movement speed, server side, to check for cheating. I do this by checking the distance between last position verified and new position sent by the client and last server time stamp when we verified the speed (distance / time). Then after verifying that the speed is ok, we timestamp the new one.
 
However, I cannot get the server to resolve the speed accurately. I assume this is because the server timestamp is not going to match the time the client traveled since the server processes much faster plus the delay from lag. The end result of the speed calculation ends up calculating the player being too slow or too fast (???) in many cases.  I obviously can't trust the dt the client sends and I can't rely on the timestamp the server uses, so... what could possibly be the solution? If anyone could give me some insight I'd appreciate it! (Using python)
Edited by vhxonline

Share this post


Link to post
Share on other sites
Advertisement
Have clients send their updates not in terms of delta-time, but in terms of clock time. "At T milliseconds after midnight Jan 1, 1970, I was at X,Y". The server doesn't really care about what the client's timezone is, so long as the client's clock increases monotonically at approximately the same rate as the server's clock.
 
Or have the server establish a synchronized game-world tick time (several articles about this here on GameDev) and have the client send its updates in terms of that clock time. Never send delta-times across the network, because there's no way of being sure what the instantaneous delivery lag is going to be. That's why clock-synchronization algorithms (which iteratively work to make two clocks approach synchronization) exist.
Edited by Wyrframe

Share this post


Link to post
Share on other sites

Thanks for the response. I have tried sending the timestamp of time.time() and then setting calculating distance / (newTime - oldTime), but it still does not calculate correctly. It's odd considering both the server and client are running on the same machine so the actual timestamp should work here. Maybe the timing isn't accurate enough?

Share this post


Link to post
Share on other sites


I also have an estimated movement speed, server side, to check for cheating.

 

If you really want to combat cheating, then you have this backwards.  The server needs to be the authority on all aspects of gameplay.  The client transmits user input to the server and the server runs the game simulation based on that input.  The client also runs the simulation for the player as well, but when the two simulations invariably go out of sync, the server is the master and the client is responsible for resyncing.

Share this post


Link to post
Share on other sites

According to https://docs.python.org/2/library/time.html , the function time.time() provides guarantee only that the resolution is at worst one second. Find a time source with double-digit-milliseconds, or finer, resolution, such as time.clock().

I have looked at that and time.clock() is meant for processor time of the current application so it doesn't work from sending across client -> server. However, when timing things in the application, it's definitely a lot more accurate.

 

Hey there. Have you read Fix you time step. it may help out if not its a good read any way.

I have looked at the fixed time step and have tried to get it to work but there is still the imprecision of the system timers. Even if I have a set time step (1 / 100), if I do: distance / (currentTime - oldTime) it will never come out with the correct speed (even using the client). I'm guessing due to imprecisions of timers?

 

I update once every roughly every 0.2 seconds. Sending the movement packet with new time and position.

So for example, total distance: 22.1180555556, total dt spent: 0.243055555556. How much real time elapsed: 0.200000047684. 

 

Even if I got the fixed time step working, the server still needs to somehow verify the timestamp sent by the client is accurate somehow.

 

Maybe I am missing the concept behind the time step? It's to keep each step the same distance regardless of FPS, right?

 

 


I also have an estimated movement speed, server side, to check for cheating.

 

If you really want to combat cheating, then you have this backwards.  The server needs to be the authority on all aspects of gameplay.  The client transmits user input to the server and the server runs the game simulation based on that input.  The client also runs the simulation for the player as well, but when the two simulations invariably go out of sync, the server is the master and the client is responsible for resyncing.

 

Initially this is what I did, however I ran into problems. Among other problems in combat, anyone with greater than 100 ms of delay, the gameplay became completely unacceptable. I talked with some other game developers and they mentioned most online games just verify the speed and let the client control movement.

Edited by vhxonline

Share this post


Link to post
Share on other sites

I have looked at that and time.clock() is meant for processor time of the current application so it doesn't work from sending across client -> server. However, when timing things in the application, it's definitely a lot more accurate.

Ignore the time the client is sending. Always use one clock source (server, or client) for calculations; if you're not synchronizing clocks between client and server, you can't trust that the clocks are synchronized. So have the server check the client's sent position periodically, and have it determine the speed of the player based on the server time elapsed between received client positions, based strictly on the time the server received those positions. Use time.clock() on the server side to get the precision you need.
Edited by Wyrframe

Share this post


Link to post
Share on other sites

I apologize, I should have mentioned I did try that. However, behavior was still not as expected. It actually made it bizarre.

 

Every >= .2 seconds on the client I send the update packet. Looking at the logs the client sent the message after (example) 0.202649094381 seconds. However, the server side saw the time calculated since we got the last packet as: 0.19164764274 seconds. This seems to happen intermittently (client: 0.202243417922 vs server: 0.20065745487) somehow server is calculating the time faster than the client sends it + network latency. Surely it can't be that imprecise? I don't understand... any thoughts?

Edited by vhxonline

Share this post


Link to post
Share on other sites

Every 0.2 seconds is far too often, if we're talking typical MMORPG world scale and travel rates. Try every 2-5 seconds. If you're talking about a racing game, you need a better synchronization solution than realtime clock time in the first place; set up a clock based on physics ticks, for example.

 

You might be having some semantic trouble with the distinction between frequency and precision; sampling someone's position every approximately-2 seconds has huge error bars if your clock updates every precisely-1 seconds (that is; its values are in multiples of 1.0 seconds). The time you sampled their position could be up to +/-0.5 seconds from the true time you sampled at, depending on when your sample was relative to the nearest clock tick. Hence why a more precise clock (one precise to, for example, the nearest millisecond = 0.001 seconds, where your temporal sampling error is +/-0.0005 seconds) is valuable even for very low sampling rates (checking speed every 2 seconds, e.g. 0.5 Hz).

 

The reason you're seeing jitter there is because sometimes the packet makes it to the server faster than the previous packet did. A lower sampling rate will help squash the contribution that variable travel time makes to the equation.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!