GMS 2 Networking: Determine how long a packet took to arrive


Just for some increased visual performance in a real-time multiplayer game I'm developing, I would like to "roll-back" positions and reapply all input in order for an elapsed amount of time based on how long a player's "input" packet took to arrive.

Basically, I will store a circular buffer (basically a 2D array with a pos variable that increments and %= (mod) by the length of the array every increment) of past positions, input, and times for the other player (game is 2-player). When you receive an input/state packet for the other player, you should roll back to a certain index (x position) in the array based on how long the packet took to arrive, and overwrite the position (x,y) information, input information, etc. and resimulate, one frame at a time, the physics and positions for that player.

The reason why I want to do this is that currently, it's very noticeable that the other player stops moving, and slowly glides to their local position (the server is non-authoritative over player positions, since the game is just a story based game with no competitive aspect). They walk in a very bouncy/floaty manner right now, and it is not game-breaking at all, just annoying to look at.

The position of the other player has very little to do with the actual game properties. It's almost entirely just eye-candy that you can even see the other player. You cannot interact with them physically, and the server will just believe whatever the client says (again, cheating is allowed since there is no competition in the game).

Anyways, how can I calculate how many milliseconds (not seconds, it's too inaccurate) it took for a packet sent from one player to arrive at the other player? I had an idea that involved calculating weird stuff and sharing current_time between the players, etc. but it didn't have a direct answer and gamemaker has no way to get UNIX time in milliseconds (you can get it in seconds using date_time functions).

How can I calculate the amount of time a packet took to arrive at another player's machine? OR how can I calculate UNIX time in milliseconds (seconds are too inaccurate)?

Thank you so much.


You could give every client two variables that hold the time that has passed since the game has started. Then every time you send a packet you also send how much time since game start it was sent, and when it arrivés you calculate the difference in the client current time and the packet time.

This way you only have to sync time variables once, being the time variables at the start of the game


I think given your use case the solution you're proposing is overkill. Circular buffers with state/input replays are typically used to resolve discrepancies in fast-twitch games where player influence is the foundational element (think online first person shooters and the like).

I'd suggest focusing on the way that position corrections for non-local player(s) are applied on local. If an accurate state isn't important then it doesn't matter if the non-local player is substantially delayed behind their "true" position, so long as the *way* they move "looks right". In fact, you might go so far as to just store the non-local player's most recently stated position, and then just path their avatar to that location in a way that looks correct, instead of paying attention to the non-local inputs. I say this because your principal complaint is about how the non-local player appears, and because you downplay the importance of accuracy.

Anyhow, current_time is a good way to take measurements of milliseconds. From there you can calculate round-trip latencies (i.e. pings) by time-stamping an outbound packet, then subtracting the current time when that packet is parroted back from the other machine. Practically speaking the the best you can do for one-way latencies is taking the ping and dividing by two. Without additional infrastructure and other wizardry determining one way delays in computer networks isn't possible:


Thank you, you really answered my question well. I'll probably just continue lerping from current local position to stated non-local position, since it isn't super relevant.