Skip to main content

Network Architecture

This documentation describes the client-side network architecture that has been implemented for the R-Type project.

🎯 Overview

The client network architecture follows the same pattern as the rest of the project: abstract interfaces + concrete implementations. This allows easily changing the networking library (Boost.Asio → other) without impacting client code.

┌─────────────────────────────────────────────────────────┐
│ Client Game Loop │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ INetworkClient (Interface) │
│ • connect/disconnect • send messages │
│ • callbacks • state management │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ NetworkClientAsio (Implementation) │
│ • UDP Socket (Boost.Asio) • Async I/O │
│ • Network Thread • Message Queue │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ Game Server │
│ (localhost:8080) │
└─────────────────────────────────────────────────────────┘

🏗️ Detailed Architecture

1. Abstract Interface (INetworkClient)

┌─────────────────────────────────────────┐
│ INetworkClient │
├─────────────────────────────────────────┤
+ connect(address, port) : bool
+ disconnect() : void
+ isConnected() : bool
+ getState() : NetworkState │
│ │
+ sendLogin(username) : bool
+ sendInput(inputMask) : bool
+ sendDisconnect() : bool
+ sendAck(sequenceId) : bool
+ update() : void
│ │
+ setOnConnectedCallback(...)
+ setOnDisconnectedCallback(...)
+ setOnLoginResponseCallback(...)
+ setOnEntitySpawnCallback(...)
+ setOnEntityPositionCallback(...)
+ setOnEntityDeadCallback(...)
+ setOnScoreUpdateCallback(...)
+ setOnErrorCallback(...)
└─────────────────────────────────────────┘

Responsibilities:

  • 🔌 Connection/disconnection management
  • 📤 Sending messages to server
  • 📥 Receiving messages from server
  • 🔄 Callbacks for network events
  • 📊 Connection state management

2. Boost.Asio Implementation (NetworkClientAsio)

┌─────────────────────────────────────────┐
│ NetworkClientAsio │
├─────────────────────────────────────────┤
- _ioContext : io_context │
- _socket : udp::socket │
- _serverEndpoint : udp::endpoint │
- _networkThread : thread │
- _state : NetworkState │
- _sequenceId : uint32_t
- _pendingMessages : queue │
- _messageQueueMutex : mutex │
├─────────────────────────────────────────┤
+ connect(...) : bool
+ sendMessage(...) : bool
+ processReceivedData(...) : void
+ runNetworkThread() : void
└─────────────────────────────────────────┘

3. Utilities (NetworkMessage)

┌─────────────────────────────────────────┐
│ NetworkMessage │
├─────────────────────────────────────────┤
│ Static Methods:
+ createLoginPacket(...)
+ createInputPacket(...)
+ createDisconnectPacket(...)
+ createAckPacket(...)
│ │
+ validatePacket(...)
+ getPacketSize(...)
+ getSequenceId(...)
+ getOpCode(...)
│ │
+ inputMaskToString(...)
+ entityTypeToString(...)
+ opCodeToString(...)
└─────────────────────────────────────────┘

📦 Supported Network Protocol

Client → Server Messages (C2S)

C2S_LOGIN (1):
┌─────────────────┬─────────────────┐
│ Header │ LoginPacket │
├─────────────────┼─────────────────┤
│ opCode: 1 │ username[8] │
│ packetSize: 15 │ │
│ sequenceId: X │ │
└─────────────────┴─────────────────┘

C2S_INPUT (4):
┌─────────────────┬─────────────────┐
│ Header │ InputPacket │
├─────────────────┼─────────────────┤
│ opCode: 4 │ inputMask: byte │
│ packetSize: 8 │ (UP|DOWN|...) │
│ sequenceId: X │ │
└─────────────────┴─────────────────┘

C2S_DISCONNECT (3):
┌─────────────────┐
│ Header Only │
├─────────────────┤
│ opCode: 3 │
│ packetSize: 7 │
│ sequenceId: X │
└─────────────────┘

Server → Client Messages (S2C)

S2C_LOGIN_OK (10):
┌─────────────────┬─────────────────────────┐
│ Header │ LoginResponsePacket │
├─────────────────┼─────────────────────────┤
│ opCode: 10 │ playerId: uint32 │
│ packetSize: 15 │ mapWidth: uint16 │
│ sequenceId: X │ mapHeight: uint16 │
└─────────────────┴─────────────────────────┘

S2C_ENTITY_NEW (11):
┌─────────────────┬─────────────────────────┐
│ Header │ EntitySpawnPacket │
├─────────────────┼─────────────────────────┤
│ opCode: 11 │ entityId: uint32 │
│ packetSize: 20 │ type: byte │
│ sequenceId: X │ x: float, y: float │
└─────────────────┴─────────────────────────┘

S2C_ENTITY_POS (12):
┌─────────────────┬─────────────────────────┐
│ Header │ EntityPositionPacket │
├─────────────────┼─────────────────────────┤
│ opCode: 12 │ entityId: uint32 │
│ packetSize: 19 │ x: float, y: float │
│ sequenceId: X │ │
└─────────────────┴─────────────────────────┘