-
Notifications
You must be signed in to change notification settings - Fork 0
RFC 001 High Level Network Protocol
-
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.
-
Endianness: Little Endian (Standard for x86/ARM).
-
Serialization: Packed C-style structs (aligned to 1 byte if necessary).
-
Coordinates:
int(World Space). -
IDs:
uint32_tfor Entity IDs.
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 |
0x01 |
1 | Move the player ship up. | |
DOWN |
0x02 |
2 | Move the player ship down. | |
LEFT |
0x04 |
4 | Move the player ship left. | |
RIGHT |
0x08 |
8 | Move the player ship right. | |
SHOOT |
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 gamePacket 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.
| 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. |
| 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 |
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
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
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
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