From "Quake 3 Networking Primer":

The server accepts client commands as they arrive. It makes one call to the VM per client command. This is the only time that players are ever updated. (That's why, when someone has a bad connection from their client to the server, they'll freeze in place or skip.) (See ClientThink() in g_active.c)

If this is true, then how does the server handle jumps and gravity when clients dont send any input?

  • \$\begingroup\$ From what I understand, gravity is applied on server, then synced with every client. Also to hide lag the client applies gravity too (but does use it only for showing the user more smooth movement between syncs), and if it predicts inaccurately, on the next sync it's all just overriden. Same goes for other game activities too \$\endgroup\$ – Igor S. Oct 12 '15 at 19:17
  • \$\begingroup\$ Not sure about Q3. But in OpenArena, which basically runs on the same engine, laggers and disconnected players indeed freeze in the air. \$\endgroup\$ – 1000ml Dec 23 '15 at 4:00

In Quake 3 UDP sockets are used to issue player commands. This establishes the master gamestate which is responsible for being the "true" state of things. Each client has their own collection of 32 gamestates (snapshots) as well as a dummy snapshot for deltas. Game state variables are established before the map loads (like gravity and sit in the g_* namespace). These are effectively constant factors of the master state in the game. When changed they need to be updated via a reliable message--that is all players must receive the new state. AFAIK, g_* doesn't get applied until a map restart.

Each player is still computing their own "master" state in a way, but the global master state that happens per ACK or out-of-sync takes control. When you see skipping and such you're seeing the difference of snapshots being applied and the state correcting itself (more or less) as dropped packets (amounting to unACK'd snapshots) cause havoc.

Snapshots are ACK'd and the process effectively amounts to: copy the master gamestate to the next snapshot slot. Compare the snapshots. If something doesn't match the master state, a packet is not ACK'd, etc, then the comparison fails and the delta between the last good snapshot and the current snapshot is used to create snapshot 3 for the client. It's such a simple and elegant process because the same algorithm can be used to do full updates, partial updates, or resending old/new information.

Check out Brian Hooks' (original developer) article on it: http://fabiensanglard.net/quake3/The%20Quake3%20Networking%20Mode.html

or even Fabien's article: http://fabiensanglard.net/quake3/network.php

Both are fantastic resources.

  • \$\begingroup\$ My mistake, i was referring to the server itself. Every update, if a player is falling down but not sending buttons, the server somehow have to apply gravity. But the article states that only when client sends its input it is updated on the server. This cannot be exactly true, but i haven't found how does the server handle this aspect. \$\endgroup\$ – Newbe763547634 Oct 13 '15 at 9:29
  • \$\begingroup\$ The server doesn't apply anything in regards to physics. It just maintains state. Client's locally predict and deal with the physics of movement and such then send updates. The master state then can verify between the last two states or force a new state. \$\endgroup\$ – Justin Van Horne Oct 13 '15 at 15:58
  • \$\begingroup\$ So, if the client doesn't send a single state packet, from the perspective of others client this player would be frozen? Say i jump and, in the middle of the game, i disconnect my internet connection, no "goodbye" packet is received on the server. During the time server realizes i'm no longer online, every other client would just assume i'm flying? \$\endgroup\$ – Newbe763547634 Oct 13 '15 at 17:13
  • \$\begingroup\$ No, your state is sent with an upward velocity of some vector and the state of jumping. Your action was to jump. The velocity is the result. The physics of it is that you are in a player state of jump (it's an actual enumerable state) -- So to the players would see you jump and then if you were to disconnect mid-jump the server would get a reliable packet that says you left and it would force all players to wait until everyone sync'd up for that moment. \$\endgroup\$ – Justin Van Horne Oct 13 '15 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.