"The Quake3 Networking Model" Question

Started by
29 comments, last by Prefect 19 years, 3 months ago
Barabashka: The server has to send data to each client independently (at least in the client/server model) because each client needs a different, small part of the overall game state. To build a packet that you could simple fire off to each client would require a whole heck of a lot more data, which is a huge waste of bandwidth. Since server power is easier to scale than bandwidth, we pass the hit onto the server instead.

Also note that, as currently implemented, the Q3 network model has a nasty flaw: one laggy/poor client connection can quickly slow the whole server down. This is because each time a client lags, it forces the server to send more data on the next pass. If this continues for too long, eventually the server is trying to send a whole heck of a lot of data to that client in order to catch it up. This ends up lagging every other connection, which creates a very nasty vicious cycle. They could've implemented a per-socket throttle, but for whatever reason didn't.

A far more interesting network model (IMHO), is the one they used in Tribes 2. I can't seem to find the bookmark, but google should provide the answers.
Advertisement
Quote:for each client that would be some waste of time/performance


As long as your connection can fit on a 56k modem, or even most actual broadband connections, the encryption of the data won't be a major CPU hog on the server. The amount of data (5 kilobytes per second per player, tops?) is miniscule compared to the actual throughput of modern CPUs (5 GIGAbytes per second of memory throughput -- that's a factor of a million!).

You don't need to add your own CRC, because UDP already does that for you. You might want to sign the packet, though -- typically, you'll want to use an encryption mechanism that can both sign and encrypt in the same go, although re-signing when the packet is already in the cache is really cheap.

Now, that being said, I don't recommend encrypting your data sent from the server. Signing is more important than encryption. Encryption doesn't actually give you any more security, because anything that the client can present to the user, the user can (by definition) figure out how to decrypt.

Quote:How about more data consuming things like chat messages? Would you send them again and again in every packet until you receive an ack for at least one of those packets containing the chat message? Or is it better to send those only something like every 10th frame? But wouldn't that break the delta compression mechanism?


I'm assuming the delta is not a raw, per-byte delta compression, but instead a data structure aware, variable-bit-length delta compression mechanism. Thus, it would delta-compress each individual position, heading, and other datum within the packet. Tacking on chat, or not, in the same packet does not affect that compression.

If a server gets laggy when a single player is falling behind, then that server is running with too many players for the size connection it has. That's hardly a fault of the game, rather of the operator. You have to design in enough headroom in your system (hardware/hosting) to deal with hiccups, or it's never going to stay stable.

enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
If a server gets laggy when a single player is falling behind, then that server is running with too many players for the size connection it has. That's hardly a fault of the game, rather of the operator. You have to design in enough headroom in your system (hardware/hosting) to deal with hiccups, or it's never going to stay stable.


Unless, of course the lag is caused by the client connection, which is not in the operators control. One can even picture a DOS attack based on this: a custom client designed to connect to a server and simulate lost packets and high latency, slowing down the game for everyone. From this perspective, it's the game's responsibility to minimize the impact of a single bad client on everyone else.
Quote:Unless, of course the lag is caused by the client connection


A single player lagging should not affect the other players, even if that player needs more bandwidth (i e, the benefits of delta compression shrink). There is an upper bound on the size of a state update, which is one-over-delta-compression-ratio. Typically, you might get 50% of delta compression, so one laggy client would be the same as two non-laggy clients. If you don't have space for at least one more non-laggy client on your server, I believe you're running with too little headroom.
enum Bool { True, False, FileNotFound };
Quote:Original post by Morbo
Also note that, as currently implemented, the Q3 network model has a nasty flaw: one laggy/poor client connection can quickly slow the whole server down. This is because each time a client lags, it forces the server to send more data on the next pass. If this continues for too long, eventually the server is trying to send a whole heck of a lot of data to that client in order to catch it up. This ends up lagging every other connection, which creates a very nasty vicious cycle. They could've implemented a per-socket throttle, but for whatever reason didn't.


this is wrong.

one client's sucky connection cannot lag anyone else. ever. period.

per socket throttling (rather per client) is implemented. indisputable fact. all packets to each individual client obey rate settings, always. if the data to be sent would exceed the rate, their snaps are delayed so they will always stay under the client rate setting.

client lost packets, etc also do not generate any more work for the server. snaps are generated fresh every frame, regardless of whether a client acknowledged them or not. large snaps are typical when clients enter new clusters or when a bunch of new entities are spawned, so theres no difference really for snaps from dropped frames vs snaps from "normal" gameplay.
[=^_^=]http://bani.anime.net/etpro/ - ETPro websitehttp://bani.anime.net/banimod/forums/ - ETPro discussion forums
just to make sure if i got this right

instead of sending the client the coordinates ... of a player you send the curpos-laspos so your numbers get much smaller and you spare a few bits

analog for the rest of the gamestate data


what about values that didn t change considerably? e.g. a angle differs only 1 degree or if a player is 72 units large and the positio differs only a few units 0-4?

you wouldn t update in this case right?


i would implement a 16 oder 32 integer at the top of the gamestate where i set flags whether this variable has changed or not

how often do you update gamestates per second 6 8 12 times?
http://www.8ung.at/basiror/theironcross.html
That's not what delta means, at least not for the Quake 2 and Half-Life protocols. Quake 3 might be different, but I really doubt it, because it only makes things more complicated.

Delta simply means that of any structure (e.g. entity data) only the fields that have changed since the last acknowledge state are sent. The fields that did change are sent in their entirety. So the data that updates a structure has a small header bitfield indicating which fields are resent, followed by the data itself.

Fields are always updated if changed, even if the changes are minor. However, at least Half-Life uses bit packing and is rather aggressive about how many bits per field are used. IIRC game updates are sent at a fixed rate, while the client sends commands at the client frame rate.

cu,
Prefect
Widelands - laid back, free software strategy
In addition to bit packing, you may want to use a variable-length encoding of certain fields. Especially if the fields themselves are sent as a differential to the last-acked value, most changes will be small.
enum Bool { True, False, FileNotFound };
Quote:Original post by Basiror
how often do you update gamestates per second 6 8 12 times?


sv_fps determines the number of updates per second the server will try to send. its usually 20 in quake3.
[=^_^=]http://bani.anime.net/etpro/ - ETPro websitehttp://bani.anime.net/banimod/forums/ - ETPro discussion forums
Quote:Original post by Prefect
That's not what delta means, at least not for the Quake 2 and Half-Life protocols. Quake 3 might be different, but I really doubt it, because it only makes things more complicated.


I thought that delta compression algorithm is all about sending differences and not all data. Using delta u can pack position (x,y,z data) with very good accuracy, but still bit packing is very useful.

This topic is closed to new replies.

Advertisement