Every frame both client and servers are sending a jake2.qcommon.network.messages.NetworkPacket to each other. Each such packet contains a header and several (Client|Server)Messages
Such packets/messages are sent ad-hoc and don't require a running map instance, therefore could be sent by not connected clients.
They are sent separately, not as a part of jake2.qcommon.network.messages.NetworkPacket.
Mostly such packets contain a single string (though there are some cases when 2 strings are sent - info
& print
)
see jake2.qcommon.network.messages.ConnectionlessCommand
Since quake2 utilizes only UDP protocol, reliability should be handled by the quake2 engine itself. Each frame server tries to send a reliable message first, then if there is room append an unreliable buffer and send.
Check the jake2.qcommon.network.Netchan.Transmit
TBD
The bulk of the network traffic between server & client constitute entity updates and move messages. In order to minimize the amount of information sent over the network quake2 protocol uses delta compression - an attempt to send only the difference from the previously sent command. The following messages use delta compression:
PlayerInfoMessage
(from server)PacketEntitiesMessage
(from server)MoveMessage
(from client)
The approach is the same for all of them - first identify what fields have changed (deltaFlags
, like a bitmask), then sent only those fields.
see package jake2.qcommon.network.messages.server
see package jake2.qcommon.network.messages.client
see jake2.server.ClientStates
The following diagram illustrates client/server communication when client connectos to server. Starting from typing connect 'someaddress' and until client becomes connected and receives the updates from the server.
Network package should expose only message classes and couple of source/sink classes/interfaces for them. Nothing else is relevant and should be hidden with package private visibility.
Example of the network api:
// holding the network connection state, manages reliability, checksums, etc
class <T> NetworkConnection {
// called multiple times per frame by client/server modules
void sendConnectionLessPacket(...)
// called multiple times per frame by client/server/game modules, adds the message to the pending queue
void write(T)
// called once every frame, packs all pending messages into packet and transmits over the network
void flush()
// called every frame, unpacks the packet of incoming messages and validates
Collection<T> receive()
}