Network Subsystem¶
Overview¶
The Network Subsystem is a critical part responsible for managing the network communication of the game engine. Leveraging the Asio and ReflectCPP libraries, this subsystem handles several key responsibilities:
Network initialization
Connection management
Data transmission
Packet processing
Error handling
Protocol¶
The network subsystem uses a custom protocol to manage communication between the server and clients. The protocol is designed to be the most user-friendly and efficient as possible, that’s why we’re using ReflectCPP to serialize packets with bson.
Packet Structure¶
Each packet is double serialized, first with the data you want to send, and then with the packet header.
The packet header has the following structure:
#pragma once
#include <vector>
#include <cstdint>
#include <rfl/Bytestring.hpp>
namespace BBOC
{
struct Packet
{
std::size_t type;
std::int32_t order;
std::uint8_t index;
std::uint8_t count;
std::uint32_t checksum;
rfl::Bytestring data;
};
}
type: The type of the packet used to recognize the packet.order: The order of the packet in the sequence.index: The index of the packet in the fragment.count: The total count of the packet in the fragment.checksum: The checksum of the packet for error or corruption detection.data: The compressed serialized data.
Packet Fragmentation¶
To avoid packet loss, we use packet fragmentation. If the packet is too big, we split it into smaller packets and send them separately.
Packet Recovery¶
If a packet is lost, we send a missing packet request to the sender to resend the lost packets.
Packet compression¶
To reduce the size of the packet, we compress the serialized data with the Zlib library.
Packet Types¶
Client¶
Type |
Packet ID |
Description |
|---|---|---|
000 |
Connection request |
|
001 |
Disconnection request |
|
002 |
Input pressed |
|
003 |
Input released |
|
004 |
Joystick move |
Server¶
Type |
Packet ID |
Description |
|---|---|---|
100 |
Update actor properties |
|
101 |
Remove actor |
|
102 |
Update camera properties |
|
103 |
Change world |
|
104 |
Game synchronize |
Meta¶
Type |
Packet ID |
Description |
|---|---|---|
200 |
Ping request |
|
201 |
Missing packet |
Packet Definitions¶
Client¶
Client Connection¶
Send a connection request to the server.
Packet Id: 000
Packet Structure¶
#pragma once
namespace BBOC
{
struct ClientConnectionDto
{
};
} // BBOC
Client Disconnection¶
Send a disconnection request to the server.
Packet Id: 001
Packet Structure¶
#pragma once
namespace BBOC
{
struct ClientDisconnectionDto
{
};
} // BBOC
Client Input Pressed¶
Send a pressed input to the server.
Packet Id: 002
Packet Structure¶
#pragma once
namespace BBOC
{
struct ClientInputPressedDto
{
int key;
};
}
Client Input Released¶
Send a released input to the server.
Packet Id: 003
Packet Structure¶
#pragma once
namespace BBOC
{
struct ClientInputReleasedDto
{
int key;
};
} // BBOC
Client Joystick Move¶
Send a joystick move to the server.
Packet Id: 004
Packet Structure¶
#pragma once
namespace BBOC
{
struct ClientJoystickMoveDto
{
int joystickId;
int axis;
float position;
};
} // BBOC
Server¶
Server Update Actor¶
Update actor properties.
Packet Id: 100
Packet Structure¶
#pragma once
#include "bboc/engine/subsystem/network/dto/server/ServerUpdateComponentDto.hpp"
#include "bboc/engine/util/UID.hpp"
#include "rfl/Bytestring.hpp"
#include <vector>
#include <optional>
namespace BBOC
{
struct ServerUpdateActorDto
{
UID id;
UID worldId;
UID actorType;
double positionX;
double positionY;
double scaleX;
double scaleY;
double rotation;
bool followCamera;
std::vector<ServerUpdateComponentDto> componentsData;
std::optional<rfl::Bytestring> actorData;
};
} // BBOC
actorType: The type of the actor defined by the registered actor order in the game.componentsData: The serialized components data see Component Handling for more information.actorData: The serialized actor data see Component Handling for more information.
Server Remove Actor¶
Remove actor.
Packet Id: 101
Packet Structure¶
#pragma once
#include "bboc/engine/util/UID.hpp"
namespace BBOC
{
struct ServerRemoveActorDto
{
UID id;
UID worldId;
};
} // BBOC
Server Update Camera¶
Update camera properties.
Packet Id: 102
Packet Structure¶
#pragma once
namespace BBOC
{
struct ServerUpdateCameraDto
{
double positionX;
double positionY;
double sizeX;
double sizeY;
};
} // BBOC
Server Change World¶
Change world.
Packet Id: 103
Packet Structure¶
#pragma once
#include "bboc/engine/util/UID.hpp"
namespace BBOC {
struct ServerChangeWorldDto {
UID worldId;
UID worldType;
};
}
Server Game Synchronize¶
Game synchronize.
Packet Id: 104
Packet Structure¶
#pragma once
#include "bboc/engine/util/UID.hpp"
#include <rfl/Bytestring.hpp>
namespace BBOC {
struct ServerGameSynchronizeDto {
UID worldId;
UID worldType;
rfl::Bytestring gameData;
rfl::Bytestring worldData;
};
}
Meta¶
Ping¶
Ping request.
Packet Id: 200
Packet Structure¶
#pragma once
namespace BBOC
{
struct PingDto
{
};
} // BBOC
Missing Packet¶
Missing packet.
Packet Id: 201
Packet Structure¶
#pragma once
#include <vector>
#include <cstdint>
namespace BBOC {
struct PacketFragmentDto
{
std::int32_t packetId;
std::int32_t fragmentId;
};
struct MissingPacketDto
{
std::vector<PacketFragmentDto> missingPackets;
uint32_t lastReceivedPacket;
};
}
Packet Serialization¶
To serialize packets, we use the ReflectCPP library. This library allows us to serialize and deserialize packets with ease. But this library has limitations when it comes to serializing complex data structures, so we use basic structures to serialize packets.
Example¶
struct ClientInputPressedDto
{
int key;
};
Network Schema¶
We made a schema to help us understand the network subsystem’s structure and how interactions client-server are actually working.

Component Handling¶
If you want to create a new component that uses the network subsystem, you need to inherit from the SynchronizedComponent class.
Check the
SynchronizedComponentclass in thenetwork_subsystem_component.mdfile for more information.