Network RFC for R-Type Protocol
This document describes the R-Type Protocol (RTP), a custom binary application-layer protocol designed for real-time multiplayer gaming. RTP provides a hybrid reliability model over UDP, supporting both unreliable high-frequency state updates and reliable control messages through a custom acknowledgment system. This document defines the packet structure, serialization rules, reliability mechanisms, and command definitions required for interoperability between Client and Server implementation.
Introduction
The R-Type project requires a high-performance networking architecture capable of handling fast-paced arcade gameplay. Standard TCP implementations introduce Head-of-Line (HOL) blocking and Nagle’s algorithm delays, which are unsuitable for real-time entity synchronization.
The R-Type Protocol (RTP) is designed to run exclusively over UDP (User Datagram Protocol). To mitigate the inherent unreliability of UDP, RTP implements a lightweight application-layer reliability mechanism (RUDP) for critical data, while allowing transient game state data to remain unreliable for maximum throughput.
Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 (RFC2119, RFC8174) when, and only when, they appear in all capitals, as shown here.
Data Representation
Byte Ordering
All multi-byte numeric fields (uint16, uint32, float) MUST be serialized in Little Endian byte order. This decision aligns with the native architecture of modern gaming platforms (x86_64 and ARM64), facilitating "Zero-Copy" deserialization strategies.
Structure Alignment
All data structures transmitted over the network MUST be packed with 1-byte alignment (#pragma pack(1)) to prevent compiler-inserted padding bytes from altering the packet size.
Protocol Header Structure
Every UDP datagram transmitted by either Client or Server MUST begin with the following 20-byte fixed header.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic Number | Command ID | Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Ack ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Fragment ID | Frag Index | Total Frags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Size | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Field Definitions
- Magic Number (16 bits): MUST be
0xD1CE. Serves as a protocol identifier; invalid packets MUST be dropped. - Command ID (8 bits): Type of payload (Login, Move, Shoot, etc.).
- Flags (8 bits): Bitmask defining packet behavior:
0x01(RELIABLE): Receiver MUST send acknowledgment.0x02(IS_FRAGMENT): Payload is part of a larger message.0x04(IS_ACK): Explicit acknowledgment; payload SHOULD be empty.0x08(IS_ERROR): Indicates an error; payload contains error code and message.
- Sequence ID (32 bits): Monotonic counter for ordering and loss detection.
- Ack ID (32 bits):
Sequence IDof the last valid reliable packet received. - Fragment ID (16 bits): Unique identifier for fragmented chunks.
- Frag Index (8 bits): Current chunk index (0 to N).
- Total Frags (8 bits): Total number of chunks.
- Payload Size (16 bits): Size of payload in bytes.
- Checksum (16 bits): Covers header + payload; implementations SHOULD use CRC-16-CCITT.
Reliability Mechanism
Unreliable Transmission
Packets with the RELIABLE flag unset are "Fire-and-Forget", used for high-frequency updates. Lost packets are ignored.
Reliable Transmission
Packets with the RELIABLE flag MUST be acknowledged:
- Sender: Store packet in "Sent Queue" with timestamp and track retransmissions.
- Receiver: Should piggyback
Ack IDor send explicit ACK packet (IS_ACKflag,CommandID = 0xFF). - Ack semantics:
Ack IDacknowledges all reliable packets withSequence ID <= Ack ID. Selective acknowledgment optional. - Retransmission / RTO: Measure RTT; apply exponential backoff; cap attempts (default 5). If no ACK, consider peer unreachable.
- Congestion & pacing: Avoid aggressive retransmissions; implement send-pacing or rate limiter.
Fragmentation
Maximum Transmission Unit (MTU) safe limit: 1400 bytes. Payloads exceeding this MUST be fragmented.
- Payload Size = this packet's payload only.
- Fragment payload size =
effective_fragment_size(default 1004 bytes if not negotiated). - Each fragment sets
IS_FRAGMENTflag and populates Fragment fields. - All fragments MUST be RELIABLE.
- Reassembly: validate indices, enforce limits, discard on timeout or memory cap.
- Fragment ID reuse: avoid until old reassembly complete.
- Buffer fragments until all received; validate with checksum.
Default fragment sizing: recommended 1004 bytes; allows 20-byte RTP header. Negotiation optional during login.
Command Definitions
Management (Reliable)
- 0x01 (REQ_LOGIN): Client requests connection.
- 0x02 (RES_LOGIN): Server response.
- 0x03 (REQ_JOIN_ROOM): Client joins a lobby.
- 0x04 (RES_ROOM_STATE): Room info.
Gameplay (Unreliable)
- 0x10 (C_INPUT): Client input state.
- 0x11 (S_ENTITY_STATE): World update.
Gameplay (Reliable)
- 0x20 (S_PLAYER_DEATH): Notification of entity destruction.
- 0x21 (S_SCORE_UPDATE): Global score change.
Security Considerations
- Magic Number Validation: Must check immediately.
- Buffer Bounds Checking: Ensure payload size matches header.
- Max Payload Enforcement: Drop packets > 1400 bytes.
- Sequence Validation & Replay Protection: Compare sequence numbers safely.
- Rate Limiting & Resource Caps: Limit per-client memory and fragment reassembly.
- Fragmentation DoS Mitigations: Limit simultaneous incomplete fragment reassemblies.
- Retransmission & Backoff: Cap attempts, exponential backoff.
- Handshake & Authentication: Require login handshake; use short-lived session tokens.
- Integrity / Authentication: CRC detects accidental corruption.
- NAT Traversal & Keepalive: Send periodic keepalive; drop idle sessions after 60s.
IANA Considerations
No IANA actions. Protocol runs on user-defined UDP port (default 8080).
Acknowledgements
Developed by the Epitech R-Type Serveur Robuste.