6
\$\begingroup\$

I'm making a game where an authoritative server sends information to all clients about states and positions for objects in a 3d world. The player can control his character by clicking on the screen to set a destination for the character, much like in the Diablo series.

I've read most information I can find online about interpolation, reconciliation, and general networking architecture (Valve's for instance). I think I understand everything but one thing seems to be missing in every article I read. Let say we have an interpolation delay of 100ms, server tickrate=50ms, latency=200ms; How do I know when 100ms has past on the client? If the server sends the first update on t=0, can I assume it arrives at t=200, therefore assuming that all packets takes the same amount of time to reach the client? What if the first packet arrives a little quick, for instance at t=150. I would then be starting the client with t=150 and at t=250 it will think it has past 100ms since its connect to the server when it in fact only 50ms has past.

Hopefully the above paragraph is understandable. The summarized question would be: How do I know at what tick to start simulating the client?

EDIT: This is how I ended up doing it: The client keeps a clock (approximately) in sync with the server. The client then simulates the world at

simulationTime = syncedTime - avg(RTT)/2 - interpolationTime

The round-trip time can fluctuate so therefore I average it out over time. By only keeping the most recent values when calculating the average I hope to adapt to more permanent changes in latency. It's still to early to draw any conclusion. I'm currently simulating bad network connections, but it's looking good so far.

Anyone see any possible problems?

\$\endgroup\$

2 Answers 2

8
\$\begingroup\$

There are two approaches to this.

Lock Step

In Lock Step all clients send there data for frame 1 to the server and then wait. The server collects the frame 1 data from all clients and only processes them once all are received. It then sends the result back to all clients and gives the clients the go-ahead to start working on frame two. Note that with frame here I mean 'simulation frame' the client can still continue animating, smoothing etc... The network rate could be 15FPS while the game is still looking smooth, animated at 60FPS.

The benefit of this technique is that its very easy to keep everything synchronized, as everybody just waits for each other. Its also very easy to send all information, as only what has changed (or what influenced those changes, such as key presses) needs to be send since all clients are in the same step of the simulation. The drawback is that one slow-client can make the game slower for all users.

Remember the little turtle on the bottom right while playing Age of Empires? Or the time going a lot slower than it should be in Supreme Commander? This indicated that one of the clients was slower, and it was slowing the other clients down.

Authorative (non-lockstep) server

The other approach is for the clients to not wait for each other. The clients continuously send their changes and the server approves/disapproves them on a first-come-first-served basis while also sending back the the state of the simulation on which this approving/disapproving was based. (Which is also the state the client should be at as soon as possible). There is no really synchronous beginning. (Though you should have clients wait until every other client is connected as well)

This approach is heavier on network traffic but simpler to implement and slow clients do not slow down other clients.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ You beat me by 1 minute xD. \$\endgroup\$
    – Kromster
    Aug 15, 2014 at 7:06
  • \$\begingroup\$ I've read about lock step but I don't like the concept of having the slowest client determine every other client's update rate. Each server will handle a world of approx. 30-100 players and each player will probably be able to see 2-5 other player at any given time. So alternative 2: Do I just take each received message and display it's states/positions after the interpolation delay(100ms) has past since the recieve time. For instance if I recieve a packet at t=123ms I simulate it at t=223ms? (discarding packets out of order) \$\endgroup\$ Aug 15, 2014 at 7:56
  • 1
    \$\begingroup\$ If this is your first 'networked game' I would definitely not aim for 30-100 players. Try first making a game/prototype where there are three networked players before attempting something bigger (really! this stuff is tricky). Also I would not attempt to hide lag by having the server perform tricks. I would only let the client guess what happens between packages. Make the server work as if all packages are sent/received instantly. (Lag hiding is a also a very broad and difficult subject, don't try to tackle all problems in your first multiplayer game!) \$\endgroup\$
    – Roy T.
    Aug 15, 2014 at 9:30
  • \$\begingroup\$ This is my 4th networked game so I'm aiming for something a little higher than 3 players. I've had success with interpolation in my previous games but I want to improve and make it better. What I did in my last game was to timestamp all updates sent from the server and then interpolate between the two updates before and after the simulation timestamp on the client(using a interpolation delay of 100). When I sent the initial world state to the player I also sent the current timestamp and then I increased the client's timestamp independently hoping it would stay in relative sync to the server. \$\endgroup\$ Aug 15, 2014 at 9:57
  • \$\begingroup\$ In that case, can you maybe make your question more specific, or show an example of what didn't work out using that model? \$\endgroup\$
    – Roy T.
    Aug 15, 2014 at 10:16
3
\$\begingroup\$

There are 2 approaches to that

You make clients synchronized - Lock-Step model:

Firstly - read this 1500 Archers on a 28.8: Network Programming in Age of Empires and Beyond. It's about RTS, but from your description that applies to your game as well.

Every client gets a Tick 0 moment (e.g. server sends message to start in MaxLag - ClientLag ms to all clients) and runs it's local timer from that.

Now when messages arrive early they are queued for execution at a later point, so not to break order of events. We want every client to do A B C on exactly the same ticks in exactly that order. Early execution is not allowed, because it will make clients states loose sync.

When tick occurs and there'a yet no message arrived, client should pause and wait for the message (that's lag that player sees).

You make the server keep the logic

This way you make the server to do all the games logic. Clients are only displaying the most recent state (whatever that is) and collect players actions and send them to server. In this case you don't care about timing and just display ASAP. That is usually used in racing games and FPS, where things need to be fast and precision is not that important.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .