🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Specifics of Client/Server interaction using TCP

Started by
2 comments, last by hplus0603 8 years ago

I've been reading up a lot on Game networking and at this point I'm very confused on what I need to do in a client/server setup.

My question stems from this Gaffer on Games article. Mainly the bit about a pure client/server setup.

In a pure client/server model you run no game code locally, instead sending your inputs such as key presses, mouse movement, clicks to the server. In response the server updates the state of your character in the world and replies with a packet containing the state of your character and other players near you. All the client has to do is interpolate between these updates to provide the illusion of smooth movement and BAM you have a networked client/server game.

Inputs would then be time sensitive, right? So you would have to tell the server when each input happens in relation to the last/next input?

How would you accomplish this? Send a long representing a tick number on the client side so that the server knows when the commands happened? (pressed left at tick 50, released left at tick 342, pressed up at tick 345) Or am I misunderstanding the term "command"?

My next question is in regards to what gets sent out to all clients (state updates or commands). I've asked this question before but I think I misunderstood the answer. Here's what I thought was the correct way to handle this entire interaction (just movement):

Client sends raw position updates (not commands) -> Server does validity checks then sends that update to all clients in area

OR

Client sends movement command (like move east from this position) -> Server accepts command and applies to simulation

Server is on a loop that sends delta updates to all clients (raw positions and interpolate on client)

Advertisement

Inputs would then be time sensitive, right?


They don't have to be, but they should be. You've got roughly the right idea on how to handle it. The server and client need to roughly agree on what a particular tick means (e.g., tick X after start of multiplayer session, or something). Latency (RTT) measurement/adjustment is still going to be necessary to get good results.

My next question is in regards to what gets sent out to all clients (state updates or commands).


State updates, generally. Commands can be rejected or modified based on server simulation state, and you want to send the results of the command rather than the command itself. e.g., there's no reason to send the FireWeapon command to all clients if the server rejects the original, or the server might instead send an OutOfAmmo event to all clients so they know to play a "click-click-click" sound or the like.

Client sends movement command (like move east from this position) -> Server accepts command and applies to simulation
Server is on a loop that sends delta updates to all clients (raw positions and interpolate on client)


Close, but not deltas. Just send the actual values. Deltas imply that you can't tolerate lost updates.

You can mostly get by with three broad categories of messages:

- Unreliable, ordered. Updates to properties that change very frequently and so you can just constantly emit the most up-to-date value over the wire. If an update gets lost, there's no need to retransmit, because a new value will be sent anyway. Ordering matters because you don't stale delayed packets to override data from more recent packets. ex: position data for moving objects.
- Semi-reliable, ordered. Updates to properties that change infrequently but you only need to know about the most recent value. If an update gets lost, you must retransmit, but instead of retransmitting the lost update you can send the current value, because you don't need intermediate values. In other words, the message itself is reliable, but the server is free to update the message with new values, rather than having to add new messages. Ordering matters because stale packets should not override more recent packets. ex: hit points, active inventory item, position data for stationary objects (inc. previously-moving objects).
- Reliable, unordered. Fire-and-forget events that a client needs to know about. Losing the event would result in a broken or unsatisfactory play experience, but the order of application does not matter. ex: triggers for sfx or vfx such as s weapon being fired, chat messages.

I posit that you never strictly need reliable ordered messages (e.g., TCP) for real-time gameplay (though it's probably a far better choice outside of the real-time parts of the game, e.g. for browsing DLC or the like). Also note that you never need truly unreliable messages: if you don't care if it ever arrives, don't send it in the first place.

Sean Middleditch – Game Systems Engineer – Join my team!

Thank you for the response!

tick X after start of multiplayer session, or something

Say the server receives a command that is 5 ticks late (Command A tick = 10, Command B tick = 25 but server receives Command A on tick 40 and B on tick 60). How would you compensate for that lag? If it's movement commands then your position would be off. Would you just correct the client?

This question comes up every two weeks! In fact, the three main networking models mainly separate themselves by how they deal with this case.

There's a thread just a few ticks down that talks about this in some detail.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement