class_name Protocol extends RefCounted ## Wire constants. Bump [constant VERSION] whenever a codec layout changes; the ## server refuses mismatched clients at handshake rather than desyncing later. ## 2: added spawn-grace flag + cleared countdown to the snapshot, and the ## roster message. ## 3: dropped the post-hit invulnerability flag, added the respawn-lockout byte ## to each player record. ## 4: added SimEvent.Type.PLAYER_FIRED. It was inserted mid-enum, which shifts ## the wire value of every event after it -- a mismatched client would ## mis-decode every hit and death, so the handshake has to reject it. ## 5: handshake carries an auth ticket instead of a bare name; added character ## list/select/create messages, per-player max health and colour in the ## snapshot. ## 6: inventory and loot. The snapshot gained the observer's own inventory and ## the ground-loot list, the input frame gained a slot byte, and three item ## events were appended. Every one of those changes the byte layout of a ## message both ends parse positionally. ## 7: more than one dungeon. enter_instance carries a portal LIST and the id of ## the dungeon you are standing in, replacing the single portal position. ## 8: upgrades. A new server -> client upgrade-state message, a new ## client -> server choice message, and two more SelectResult values. ## 9: telegraphed boss attacks. A new TELEGRAPH event, appended to the enum. const VERSION := 9 const DEFAULT_PORT := 27015 const MAX_CLIENTS := 32 ## ENet channels. Separating them stops a burst of reliable bullet events from ## head-of-line blocking the unreliable snapshot stream. const CH_CONTROL := 1 ## handshake, instance transitions -- reliable const CH_SNAPSHOT := 2 ## world state -- unreliable, newest wins const CH_EVENTS := 3 ## bullet spawns/despawns, hits -- reliable ordered const CH_INPUT := 4 ## client -> server intent -- unreliable ordered ## Must be identical on both ends, and larger than the highest channel above. const CHANNEL_COUNT := 8 enum InstanceKind { LOBBY, DUNGEON } ## Why a character selection failed. Sent rather than a bare "no", so the UI can ## say something useful instead of appearing broken. enum SelectResult { OK, NO_SUCH_CHARACTER, CHARACTER_IS_DEAD, LIMIT_REACHED, NOT_AUTHENTICATED, ## Swapping is hub-only. Allowing it inside a dungeon would be an instant, ## uninterruptible exit from danger -- strictly better than the one-second ## escape channel, and it would make that channel pointless. NOT_IN_HUB, ## Upgrades are spent standing at the hub's NPC. Same rule as the portal: ## where you are is the one thing a modified client cannot fake. NOT_AT_THE_NPC, ## No unspent level-up, or an option index that was not on the table. NOTHING_TO_CHOOSE, } ## Player flags packed into the snapshot's per-player byte. const F_ALIVE := 1 const F_ESCAPING := 4 ## Arrival protection: invulnerable and unable to shoot. The only invulnerable ## state there is -- see the i-frames note in SimConfig. const F_SPAWN_GRACE := 8 ## The peer behind this player has dropped and is being channelled out. const F_LINKDEAD := 16 ## Snapshot's cleared-countdown byte when the instance is not in the cleared ## state -- 30s fits in a byte, so 255 is free to mean "not applicable". const COUNTDOWN_NONE := 255