4
\$\begingroup\$

I am attempting to write a proof of concept in preparation to do my first networked game. I have decided to do an authoritative server with client side prediction.

I am trying to implement my architecture like this diagram from an excellent article on the subject

Client Server Architecture example

In the article, the data that is synchronized is the player's position. This works great for turn based games, but what about real time games?

In my game, each entity has a position and a velocity vector. It is the server's job to detect collisions. I have attempted to send the server velocity changes, but I am having an issue where the server's position and the client's position begins to diverge because their clocks are not perfectly synchronized.

So my question is, is it standard practice to send positions as the synchronized state between a client and server instead of a velocity vector? Will changing to synchronizing positions instead of velocities open my game up to cheating? Is there a better way to synchronize the players' states with the server?

Also, if I use positions, doesn't that mean that the other players are going to be seen in a past state? Will that mean that the server might send a player killed message before the collision is visible to the player in the present?

\$\endgroup\$

2 Answers 2

7
\$\begingroup\$

Making good multiplayer games isn't a trivial thing, we know. There are many aspects to care about: network architecture, machines synchronization, network delays, cheating... But, let's start one step per time.

In turn-based games, as you said, you are limited to send objects positions, because that is the only important information you'll need. In real-time, fast-paced video games (such as FPS, racing games...), good timing is the key to make the game enjoyable, and mostly playable.

When playing an FPS there are many objects to sync: players, bullets, weapons, vehicles, and then scores, chat messages... The more the objects, the more the packets to send over the network, and with few to no delays independently of your connection. That means you need a proper network protocol to connect different players to play together. That means you can't rely on TCP, because you are focusing on real-time simulation and fast updates, not packets integrity and reliability. UDP is better for this task. Well, not UDP as is, but a custom net protocol built on top of it.

The image you posted shows a basic client-server interaction, where the server is authoritative over the client. That means the client always applies the information received from the server, whatever it is, because it is the server and it is always right. And it is right because it is the only one running the game logic, whilst clients are only replicating it on different machines. Also, clients should replicate exactly the server simulation: this is called deterministic lockstep. A system is said deterministic if we can know every single action to perform to get to a state B from a given starting state A.
A video game is a deterministic system: if I hold the 'move forward' key for a certain amount of time, I can foresee the position I'm going to be at (thanks, high school physics).
Deterministic lockstep - together with floating point determinism, the property of several machines to compute same results if given the same starting numbers and operations to perform - is the reason a client can simulate for a small amount of time what is happening on the server when some packets are suddendly lost, if given the right state information such as position and velocity instead of one only of them.
On the other hand, deterministic lockstep and client-server synchronization is only possible if both the client and server are running the same code, and assuming that there are no game logic delays because of internal application integrating/rendering time.

In the FPS scenario, a server must send clients many updates per second, so that they are always running the most recent simulation possible (for example 20 updates per seconds). This rate should be nor low enough to cause lag because of many server-side corrections, neither too high for the client machine to handle (we don't want to congestionate one's connection).

Syncing your game isn't just telling clients objects coordinates and velocities vectors, and updating; you must make sure clients are able to sync single entities as well as whole game session (e.g. when a player wants to join a game in progress). Or, your game should be able to compensate network latency so that shooting to a player is actually shooting to a player on the server: clients are running a simulation in the past because of networking, and there are efficient ways to prevent players from feeling frustrated for playing a "bad" game.

Now, answering your question: what info does one need to send to sync clients? The Quake source code shows how they dealt with client synchronization: the server receives from clients every players' input, and then sends every player avatar's position, speed and direction, this way - using the same physics code - both clients and server will compute the same frames after small amounts of time. Eventually the server will perform corrections over the clients, and there is some data to update instantly and other one should interpolate smoothly, but the game will maintain its logical integrity most of the time. And let's not forget client-side prediction!

You can read more about networked physics, server authority, client-side prediction and server-side compensation here. Also, the Valve Developer Community is a place full of interesting guides to understand better how their engine (and, generally speaking, any possible engine) works.

\$\endgroup\$
4
\$\begingroup\$

In addition to the excellent and compact answer by Giorgio Liggio:

is it standard practice to send positions as the synchronized state between a client and server instead of a velocity vector?

You send both and use both, they complete each other in a fault-tolerant and stretchful way. In addition, you would send events, like "client just turned his steering wheel right 20 degrees", etc.

Will changing to synchronizing positions instead of velocities open my game up to cheating?

No. You use other protection mechanisms against cheating, like encryption, packet checksums, signature checking, secret numeric questions and answers, IP and MAC address housekeeping. You are free to code your own mambo jambo :-).

Is there a better way to synchronize the players' states with the server?

See Giorgios answer and links. In addition, one way is to synchronise all invloved computers against a time server (you get a few ms of accuracy) and include a timestamp with each physics packet. Then receiving end then gets an accurate "snapshot" of the situation at a give timestamp, regardless of how fast or slow the packet was transmitted. From that on, you can correct and predict.

Also, if I use positions, doesn't that mean that the other players are going to be seen in a past state?

No matter how you do it, the other end of the wire will be in past state. Hence the correction and prediction. In addition, ... well there is a nice saying for game developers: Add fog. If you have something that maybe doesn't look so good, then hide it, that's the easiest way. If you need time to think, then distract the user. For example, hide the opponent with a huge explosion and a ka-boom that last for 1 second. Then you get 1 second time to negotiate with server and other clients whether he died or not, before you must show the result.

Will that mean that the server might send a player killed message before the collision is visible to the player in the present?

Not at all impossible, but this is more a question of your code design and logic. You have probably heard players accusing others for being cheaters, when they suddenly die without obvious reason. If it doesn't happen too often, players stay happy and want to continue using the product. A matter of gaming experience.

\$\endgroup\$

You must log in to answer this question.

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