Skip to content

RFC 001 High Level Network Protocol

Pierre Marguerie edited this page Dec 10, 2025 · 4 revisions

1. Introduction

  • Status: Draft

  • Target Layer: High-Level Game Logic (Application Layer)

  • Goal: Define the binary communication protocol between the R-Type Client and Server.

This document describes the packet structures, op-codes, and data flows required to synchronize the game state. This protocol sits on top of our custom Low-Level RUDP layer.

There is no need for a header since the Low-level library will put it before sending.

Important

This protocol assumes that packet ordering, reliability, and connection handshakes are handled by the lower layer.

2. Conventions & Data Types

  • Endianness: Little Endian (Standard for x86/ARM).

  • Serialization: Packed C-style structs (aligned to 1 byte if necessary).

  • Coordinates: int (World Space).

  • IDs: uint32_t for Entity IDs.

2.1. Shared Enums

Important

Use pragma packs when designing packets in header files

These enums must be consistent across Client and Server.

Action Bitmask (Input Abstraction) Used to decouple hardware keys from game logic.

Action Name Bit Position Hex Value Decimal Value Description
NONE N/A 0x00 0 No action/input detected.
UP $2^0$ 0x01 1 Move the player ship up.
DOWN $2^1$ 0x02 2 Move the player ship down.
LEFT $2^2$ 0x04 4 Move the player ship left.
RIGHT $2^3$ 0x08 8 Move the player ship right.
SHOOT $2^4$ 0x10 16 Trigger the primary weapon.
namespace game {

enum class Input
{
	kNone = 0,
	kUp = 1 << 0,
	kDown = 1 << 1,
	kLeft = 1 << 2,
	kRight = 1 << 3,
	kShoot = 1 << 4
};

}   // namespace game
State Name Value Description
GAME_OVER 1 The stage is lost.
GAME_START 2 The stage is starting.
GAME_END 3 The stage is complete
namespace game {

enum class State
{
	kGameOver = 1,
	kGameStart = 2,
	kGameEnd = 3,
};

}   // namespace game

Packet Types (OpCodes) Identify the payload type. Packet sent by the client to the server and by server to client are differentiated for code readability and error handling

Note

The op-codes start at 128 (2^7) because the low level reserves the 127 first packets op-code.

3. Payloads (Packet Definitions)

3.1 Client to Server (C2S) Payloads

OpCode Packet Name Flag Trigger/Frequency Payload Description
0x128 JOIN kUnreliable Player clicks "Join" or "Connect". 1. username(char[32]) 2.room_id(uint8_t) Player identity for the session and target game lobby ID.
0x129 START kUnreliable When the player clicks on start or restart None Ask to start the next stage
0x130 USER_INPUT kUnreliable Every network tick (~60 times/sec) or on key state change. 1. input_mask(uint8_t) Bitwise OR of GameAction enums.

3.2 Server to Client (S2C) Payloads

OpCode Packet Name Flag Trigger/Frequency Payload Description
0x150 JOIN_ACK kReliable Response to C2S_JOIN. 1. id(uint32_t)
2. status(uint8_t)
The assigned id of the player and the state of the request.
0x151 PLAYER_JOIN kReliable When a player joined the lobby. 1. id(uint32_t)
2. team(uint8_t)
3. status(uint8_t)
The id of the arrived ship, team and status of the new player.
0x152 SPAWN kUnreliable When a new entity is created (Player, Enemy, Bullet). 1. object(Entity) The new entity to create.
0x153 DESTROY kUnreliable When an entity is removed. 1. entity_id(uint32_t)
2. points_earned(uint16_t)
ID of the dead entity and earned points.
0x154 UPDATE_ENTITY_STATE kReliable When an entity changes state. 1. id(uint32_t)
2. state(uint8_t)
ID of the entity and new state.
0x155 UPDATE_POSITION kUnreliable Every network tick (~60 times/sec). 1. id(uint32_t)
2. x(uint16_t)
3. y(uint16_t)
4. v_x(uint16_t)
5. v_y(uint16_t)
Id, position and velocity(for Dead Reckoning)
0x156 UPDATE_HEALTH kUnreliable On health change. 1. id(uint32_t)
2. hp(uint32_t)
ID and hp of the entity.
0x157 UPDATE_GAME_STATE kReliable On state change. 1. state(uint8_t) The current state of the game
0x158 WORLD_INIT kReliable On game join or start. 1. stage(uint16_t)
2. size(uint32_t)
3. entities([Entity])
The list of all the present entities to render

4. Packet Workflows (Sequence Diagrams)

4.1. The "Happy Path" (Join)

sequenceDiagram
	Participant C as Client
	Participant S as Server

	Note over C, S: Connection phase

	Note over C, S: Joining phase

	C-->>S: JOIN

	S-->>C: JOIN_ACK

	C-->>S: START

	Note over S: Server knows which<br/>room_id to start

	S-->>C: UPDATE_GAME_STATE
	S-->>C: WORLD_INIT

	Note over C: Client starts to render the game
Loading

4.2 The "Happy path" (Play)

sequenceDiagram
	Participant C as Client
	Participant S as Server

	Note over C, S: Joining phase
	Note over C, S: Playing phase

	S-->>C: SPAWN (Enemy)
	C-->>S: SHOOT
	S-->>C: SPAWN
	Note over C: Renders bullet
	Note over S: Bullets hits enemy

	S-->>C: DESTROY(Enemy)
	S-->>C: DESTROY(Bullet)

	Note over C: The Client then<br/>processes the score
Loading

4.3 Game over (Player collides Enemy)

sequenceDiagram
	participant C as Client
	participant S as Server

	Note over C, S: Joining phase

	Note over C, S: Playing phase
	Note over C, S: Entity spawning

	Note over S: Server logic detects<br/>collision with enemy

	S->>S: Player HP = 0
	S->>S: Set State = DEAD

	S-->>C: DESTROY
	S-->>C: UPDATE_GAME_STATE

    Note over C: Client draws destroyed ship<br/>and shows "Game Over" UI
Loading

4.4 Late joining (join after start)

sequenceDiagram
    participant C as Client (Late Joiner)
    participant S as Server
    
    Note over C, S: Connection phase
    Note over C, S: Joining phase

    C-->>S: JOIN

    Note over S: Server assigns Player ID<br/>and checks validity
    S-->>C: JOIN_ACK
    S-->>C: WORLD_INIT
    
    Note over C: Client spawns all existing entities.
   
    Note over S: Server updates<br/>other clients in that game
    S-->>C: UPDATE_GAME_STATE
    
    Note over C, S: 5. Normal Play Loop Resumes
    loop Game Tick
        S-->>C: S2C_UPDATE_POSITION { ... }
        C->>S: C2S_INPUT { ... }
    end
Loading