EDGE Networking =============== Topology -------- Each "client" will be connected to the "host" computer using a "reliable link", which will be TCP/IP. There is also the "broadcast link" which each client normally uses for sending/receiving "ticcmd" packets. This link will be UDP/IP. The host always uses the broadcast link if any client does. When a client doesn't use the broadcast link, the host is responsible for emulating the broadcast, in two ways: (1) ticcmds received from non-BC --> broadcasted to ALL clients (2) ticcmds received from BC --> transmitted to non-BC clients STATE: client: is_using_broadcast_link [true/false] (host needs to know this state). We assume the broadcast link can be unreliable in two ways: (1) a sent packet may not reach every client, or even any client (2) sent packets may arrive out of order. When a client thinks it has missed a broadcast packet, it asks the host for the packet using the reliable link and receives that packet (possibly some time later) also over the reliable link. When the _HOST_ thinks it missed a broadcast packet, it asks the client directly via the reliable link, and the client responds over the reliable link. Clients are comparable to what was called "Nodes" in the original DOOM networking code. Each client can be responsible for multiple players, however in practice there will only be a single _human_ player per client (and possibly some bots). Ports ----- The BASE port is set via the -port option. The default value is 26710. The reliable port on the host will always be BASE+0. The broadcast port on the host will always be BASE+1. Formats ------- There are two fundamental types of packets: binary packets and text packets, and each has their own structure. Binary packets begin with a '@' character followed by a three-letter identifier (e.g. @TIC). Then follows a 4-byte little-endian count of the data bytes in the payload, followed by the payload itself. As a sanity check the packet is terminated with a ^Z (decimal 26) byte. Text packets are Unicode UTF-8 encoded, consisting of a series of lines which are terminated by a single LF ('\n'). The very first line begins with a type keyword in square brackets ('[' and ']'). The keyword ends with a question mark ('?') if the packet expects a reply. Text packets are terminated with a single ^Z (decimal 26) byte. Each line in a text format packet is typically a series of keywords/values separated by a single space. String values are delimited by double quotes (""), and the '\' character can escape a single character. Integer values may be preceded by '0x' to denote hexadecimal numbers. Both types of packets can be sent on both the reliable and broadcast links. However the broadcast link is generally reserved for two packet types: host-discovery and ticcmds. Ticcmds are the basic aim/move/shoot messages exchanged between all the clients in the game, and are binary format. Protocol -------- For clients to discover the host via broadcasting: client broadcasts: [HOST?] host broadcasts back: [HERE] ADDRESS 192.168.0.151 For client connecting to host: client makes reliable connection client sends: [HELLO] PLAYER "Andrew" BROADCAST 1 host replies: [WELCOME] or [ERROR] MESSAGE "You ain't welcome here fella!" Host will send to clients (and itself) before game starts: (possibly multiple times) [PARAMS] GAME "HELL ON EARTH" LEVEL "MAP01" SKILL 3 MODE OLDDM (NEWDM COOP CTF LASTMAN) RANDOM_SEED 0x12345678 FLAGS 0x000104c7 [PLAYERS] 1 YOU "Matt" CONSOLE 2 YOU "Mark" BOT 3 NET "Luke" CONSOLE 4 NET "John" BOT To begin the game, Host sends to everyone: [BEGIN] GAME_TIC 0 All clients + the host will exchange Ticcmd packets: @TIC (4-byte data length) full_ticcmd_t full_ticcmd_t ... (as many as fit into data length) Each full_ticcmd_t structure contains a 4-byte gametic value (little endian) followed by a normal ticcmd_t. The plain ticcmd_t contains a 'player_idx' field. Other packets: [NOP] [GOODBYE] (can be sent both ways) [RETRANSMIT?] (can be sent both ways) GAME_TIC 123456 PLAYER 5 Networking API -------------- low level: N_OpenBroadcastLink N_CloseBroadcastLink N_BroadcastSend N_BroadcastRecv N_CreateReliableLink (host only) N_AcceptReliableConn (host only) N_OpenReliableLink (client only) N_CloseReliableLink (client only) N_ReliableSend N_ReliableRecv higher level: ??? Ideas about In-Game Joining --------------------------- Client connects to host in usual way and sends [HELLO] packet. Host replies with welcome packet and a special field: [WELCOME] GAME_IN_PROGRESS 1 Host sends to all other clients (and itself) : [PAUSE] GAME_TIC 17839 (NB: all maketics after this are forefeit) [NEW_PLAYERS] 5 NET "Jimmy" CONSOLE 6 NET "Bot99" BOT Host sends [PARAMS] and [PLAYERS] to new client. Host then sends a savegame to new client: @SAV (length) (data................) the other clients then must wait until new client has finished receiving the savegame data. Perhaps host could send progress messages to waiting clients: [PROGRESS] 75 then: host sends to every client (old, new, and itself) : [BEGIN] GAME_TIC 17839