[TOC]
This project extends a provided singleplayer Bomberman base in SDL2 with a client-server multiplayer architecture built on ENet.
The multiplayer layer is added on top of the existing gameplay scaffold rather than replacing it with a full rewrite. That keeps the original game foundation intact, while introducing a dedicated server runtime, a shared wire protocol, client netcode, multiplayer scene integration, and a diagnostics/testing layer around it.
This page gives the broad system view:
- how the project is split at runtime
- what the main ownership boundaries are
- what comes from the provided base versus what was added for multiplayer
At the highest level, the project is split into two runtime sides:
- a client process starting in
main.cpp, responsible for input, local presentation, client netcode, and multiplayer scene flow - a dedicated server process starting in
server_main.cpp, responsible for authoritative match state, round flow, and fixed-tick simulation
Between them sits a shared contract centered on Net/NetCommon.h.
That shared layer defines the packet protocol used by both client and server, including message types, payload sizes, and channel assignments.
The multiplayer gameplay layer sits above that protocol work: the client consumes authoritative updates from the server, applies client-side prediction and correction where needed, and turns the resulting state into the playable match presentation.
The project is split so that each layer owns a small and clear part of the system.
| Area | Ownership |
|---|---|
| Client | input collection, local presentation, connection state, prediction, smoothing, and client-side diagnostics |
| Server | authoritative match state, lobby/bootstrap/match flow, simulation ticks, snapshots, corrections, and reliable gameplay events |
| Shared | protocol structs, message ids, payload sizes, channel assignments, and shared diagnostics schema |
| Scene integration | client-side multiplayer scene code that turns authoritative state and client-side prediction into the visible match |
This keeps the architecture readable: the client is responsible for responsiveness and presentation, the server is responsible for gameplay truth, and the shared layer keeps the protocol explicit with a single source of truth.
That split shows where the project work is concentrated: the original local gameplay foundation remains in place, while the main extension is the multiplayer architecture built around it.
At a high level, the multiplayer loop works like this:
- the client collects local player input
- that input is sent to the server through the shared protocol
- the server advances the authoritative match state on fixed simulation ticks
- the server sends snapshots, corrections, and reliable gameplay events back to connected clients
- the client merges that authoritative data into the multiplayer scene and updates the visible match state
This is the central architectural path through the project: local input starts on the client, gameplay truth resolves on the server, and the client presents the result.
The project is split this way for a few practical reasons:
- server authority keeps shared gameplay state consistent across players
- an explicit protocol keeps the wire contract easier to validate, debug, and evolve
- client-side prediction and smoothing improve responsiveness and presentation without replacing server truth
- integrated diagnostics make the system easier to test and reason about under different network conditions
The result is a project structure that stays understandable even as multiplayer features are added on top of the original singleplayer base.
main.cppserver_main.cppNet/Server/Scenes/MultiplayerLevelScene/- selected shared
Sim/and config files used by both sides
| Previous | Next |
|---|---|
| README | Networking |