Bomberman Multiplayer
Authoritative multiplayer networking layer for Bomberman.
Loading...
Searching...
No Matches
ServerState.h
Go to the documentation of this file.
1
7#ifndef BOMBERMAN_SERVERSTATE_H
8#define BOMBERMAN_SERVERSTATE_H
9
10#include <array>
11#include <optional>
12#include <string>
13#include <string_view>
14
15#include <enet/enet.h>
16
17#include "Net/NetCommon.h"
18#include "Net/NetDiagnostics.h"
19#include "Sim/Movement.h"
20#include "Sim/PowerupConfig.h"
21
25namespace bomberman::server
26{
27 // ----- Server session constants -----
28
35 constexpr std::size_t kServerPeerSessionCapacity = net::kMaxPlayers + 4;
36
37 // ----- Input buffering constants -----
38
40 constexpr std::size_t kServerInputBufferSize = static_cast<std::size_t>(net::kMaxInputBatchSize) * 2u;
41
51
52 // ----- Match gameplay-state constants -----
53
55 constexpr std::size_t kServerBombCapacity = static_cast<std::size_t>(tileArrayWidth) *
56 static_cast<std::size_t>(tileArrayHeight);
57
60
61 // ----- Server phase -----
62
66 enum class ServerPhase : uint8_t
67 {
68 Lobby,
71 InMatch,
73 };
74
75 // ----- Accepted player metadata -----
76
85 {
86 uint8_t playerId = 0;
87 std::string playerName;
88 bool ready = false;
89 uint8_t wins = 0;
90 };
91
100 {
101 std::string playerName;
102 uint8_t wins = 0;
103 };
104
105 // ----- Live peer sessions -----
106
115 {
116 ENetPeer* peer = nullptr;
117 std::optional<uint8_t> playerId{};
118 uint32_t connectedServerTick = 0;
119 };
120
121 // ----- Match-only authoritative state -----
122
130 {
131 uint32_t seq = 0;
132 uint8_t buttons = 0;
133 bool valid = false;
134 bool seenDirect = false;
135 bool seenBuffered = false;
136 };
137
146 {
147 uint8_t playerId = 0;
148 sim::TilePos pos{};
149 bool alive = true;
150 bool inputLocked = false;
151 uint8_t activeBombCount = 0;
152 uint8_t maxBombs = sim::kDefaultPlayerMaxBombs;
153 uint8_t bombRange = sim::kDefaultPlayerBombRange;
154 uint32_t invincibleUntilTick = 0;
155 uint32_t speedBoostUntilTick = 0;
156 uint32_t bombRangeBoostUntilTick = 0;
157 uint32_t maxBombsBoostUntilTick = 0;
158
159 // ----- Input ring buffer -----
160 std::array<InputRingEntry, kServerInputBufferSize> inputRing{};
161 uint32_t lastReceivedInputSeq = 0;
162 uint32_t lastProcessedInputSeq = 0;
163
164 uint8_t lastAppliedButtons = 0;
165 uint8_t appliedButtons = 0;
166 uint8_t previousTickButtons = 0;
167
168 // ----- Consume timeline -----
169 bool inputTimelineStarted = false;
170 uint32_t nextConsumeServerTick = 0;
171
172 // ----- Warning throttles -----
173 uint16_t consecutiveTooFarAheadBatches = 0;
174 uint16_t consecutiveInputGaps = 0;
175 uint32_t nextTooFarAheadWarnTick = 0;
176 uint32_t nextGapWarnTick = 0;
177 };
178
180 struct BombCell
181 {
182 uint8_t col = 0;
183 uint8_t row = 0;
184 };
185
192 {
193 uint8_t ownerId = 0;
194 BombCell cell{};
195 uint32_t placedTick = 0;
196 uint32_t explodeTick = 0;
197 uint8_t radius = 0;
198 };
199
204 {
205 sim::PowerupType type = sim::PowerupType::SpeedBoost;
206 BombCell cell{};
207 bool revealed = false;
208 uint32_t revealedTick = 0;
209 };
210
211 // ----- Shared server session state -----
212
222 {
223 // ----- Session host and runtime config -----
224
225 ENetHost* host = nullptr;
227 uint32_t serverTick = 0;
228
229 uint32_t inputLeadTicks = sim::kDefaultServerInputLeadTicks;
230 uint32_t snapshotIntervalTicks = sim::kDefaultServerSnapshotIntervalTicks;
231 bool powersEnabled = true;
232
233 // ----- Live transport sessions -----
234
236 std::array<std::optional<PeerSession>, kServerPeerSessionCapacity> peerSessions{};
237
238 // ----- Accepted players and lobby persistence -----
239
241 std::array<std::optional<PlayerSlot>, net::kMaxPlayers> playerSlots{};
243 std::array<std::optional<DisconnectedPlayerReclaim>, net::kMaxPlayers> disconnectedPlayerReclaims{};
244
245 // ----- Active round authoritative world state -----
246
248 std::array<std::optional<MatchPlayerState>, net::kMaxPlayers> matchPlayers{};
250 std::array<std::optional<BombState>, kServerBombCapacity> bombs{};
252 std::array<std::optional<PowerupState>, kServerPowerupCapacity> powerups{};
253
256
257 // ----- Player-id allocation -----
258
259 std::array<uint8_t, net::kMaxPlayers> playerIdPool{};
260 uint8_t playerIdPoolSize = 0;
261
262 // ----- Round map selection -----
263
264 std::optional<uint32_t> fixedMapSeedOverride{};
265 uint32_t mapSeed = 0;
266
267 // ----- Lobby and round flow state -----
268
269 uint32_t currentMatchId = 0;
270 uint32_t nextMatchId = 1;
271
273 uint32_t currentLobbyCountdownDeadlineTick = 0;
274 uint8_t currentLobbyCountdownLastBroadcastSecond = 0;
275
277 uint32_t currentMatchLoadedMask = 0;
278 uint32_t currentMatchStartDeadlineTick = 0;
279 uint32_t currentMatchGoShowTick = 0;
280 uint32_t currentMatchUnlockTick = 0;
281 uint32_t currentEndOfMatchReturnTick = 0;
282 std::optional<uint8_t> roundWinnerPlayerId{};
283 bool roundEndedInDraw = false;
284
285 // ----- Diagnostics -----
286
288 };
289
290 // ----- Dispatcher context -----
291
294 {
295 ServerState& state;
296 ENetPeer* peer = nullptr;
297 net::NetDiagnostics* diag = nullptr;
298 net::NetPacketResult receiveResult = net::NetPacketResult::Rejected;
299 std::optional<uint8_t> recordedPlayerId{};
300 };
301
302 // ----- Session lifecycle -----
303
305 void initServerState(ServerState& state,
306 ENetHost* host,
307 bool diagEnabled = false,
308 bool overrideMapSeed = false,
309 uint32_t mapSeed = 0,
310 uint32_t inputLeadTicks = sim::kDefaultServerInputLeadTicks,
311 uint32_t snapshotIntervalTicks = sim::kDefaultServerSnapshotIntervalTicks,
312 bool powersEnabled = true);
313
315 void rollNextRoundMapSeed(ServerState& state);
316
317 // ----- Player-id allocation -----
318
320 [[nodiscard]]
321 std::optional<uint8_t> acquirePlayerId(ServerState& state);
322
324 [[nodiscard]]
325 bool acquireSpecificPlayerId(ServerState& state, uint8_t playerId);
326
328 void releasePlayerId(ServerState& state, uint8_t playerId);
329
330 // ----- Peer-session binding and lookup -----
332 [[nodiscard]]
333 PeerSession* bindPeerSession(ServerState& state, ENetPeer& peer);
334
336 [[nodiscard]]
337 PeerSession* getPeerSession(ENetPeer* peer);
338 [[nodiscard]]
339 const PeerSession* getPeerSession(const ENetPeer* peer);
340
342 [[nodiscard]]
343 PeerSession* findPeerSessionByPlayerId(ServerState& state, uint8_t playerId);
344 [[nodiscard]]
345 const PeerSession* findPeerSessionByPlayerId(const ServerState& state, uint8_t playerId);
346
352 void acceptPeerSession(ServerState& state,
353 PeerSession& session,
354 uint8_t playerId,
355 std::string_view playerName,
356 uint8_t carriedWins = 0);
357
364 [[nodiscard]]
365 std::optional<uint8_t> releasePeerSession(ServerState& state, ENetPeer& peer);
366
367 // ----- Match player state lifecycle -----
369 void createMatchPlayerState(ServerState& state, uint8_t playerId);
370
372 void destroyMatchPlayerState(ServerState& state, uint8_t playerId);
373
374 // ----- Fixed-tick simulation -----
375
377 void simulateServerTick(ServerState& state);
378} // namespace bomberman::server
379
380#endif // BOMBERMAN_SERVERSTATE_H
constexpr unsigned int tileArrayWidth
Tile map width in tiles.
Definition Const.h:43
Shared authoritative movement simulation primitives.
Shared client/server wire contract for the multiplayer protocol.
Session-local multiplayer diagnostics recorder and report model.
Shared multiplayer powerup types and round-setup tuning.
Session-local recorder for recent multiplayer diagnostics and aggregate counters.
Definition NetDiagnostics.h:103
NetPacketResult
Diagnostics classification for one packet attempt or receive path outcome.
Definition NetDiagShared.h:49
constexpr uint8_t kMaxInputBatchSize
Maximum number of inputs in a single batched MsgInput packet.
Definition NetCommon.h:67
constexpr uint8_t kMaxPlayers
Maximum supported player count in a game instance.
Definition NetCommon.h:54
Authoritative dedicated-server state, match flow, and fixed-tick simulation support.
Definition ServerBombs.cpp:21
bool acquireSpecificPlayerId(ServerState &state, const uint8_t playerId)
Removes a specific playerId from the free pool if available.
Definition ServerSession.cpp:148
PeerSession * bindPeerSession(ServerState &state, ENetPeer &peer)
Binds a connected ENet peer to stable live peer-session storage.
Definition ServerSession.cpp:185
void destroyMatchPlayerState(ServerState &state, const uint8_t playerId)
Destroys active in-match state for one player seat, if present.
Definition ServerSession.cpp:320
void rollNextRoundMapSeed(ServerState &state)
Chooses the seed for the next round map.
Definition ServerSession.cpp:123
void initServerState(ServerState &state, ENetHost *host, const bool diagEnabled, const bool overrideMapSeed, uint32_t mapSeed, const uint32_t inputLeadTicks, const uint32_t snapshotIntervalTicks, const bool powersEnabled)
Resets a ServerState for a new dedicated-server session.
Definition ServerSession.cpp:64
void acceptPeerSession(ServerState &state, PeerSession &session, const uint8_t playerId, const std::string_view playerName, const uint8_t carriedWins)
Commits an accepted peer session into active player metadata.
Definition ServerSession.cpp:244
std::optional< uint8_t > acquirePlayerId(ServerState &state)
Returns the lowest available playerId.
Definition ServerSession.cpp:134
constexpr uint32_t kMaxBufferedInputLead
Maximum distance ahead of lastProcessedInputSeq that a received input is allowed to be.
Definition ServerState.h:50
void releasePlayerId(ServerState &state, const uint8_t playerId)
Returns a playerId to the free pool.
Definition ServerSession.cpp:165
std::optional< uint8_t > releasePeerSession(ServerState &state, ENetPeer &peer)
Releases the live peer session bound to peer, if any.
Definition ServerSession.cpp:266
constexpr std::size_t kServerPowerupCapacity
Maximum number of hidden/revealed round powerups the server tracks at once.
Definition ServerState.h:59
constexpr std::size_t kServerBombCapacity
Maximum bombs the server stores for one match.
Definition ServerState.h:55
PeerSession * findPeerSessionByPlayerId(ServerState &state, const uint8_t playerId)
Returns the live peer session currently bound to playerId, if any.
Definition ServerSession.cpp:216
PeerSession * getPeerSession(ENetPeer *peer)
Returns the live peer session referenced by peer->data, if any.
Definition ServerSession.cpp:206
void simulateServerTick(ServerState &state)
Advances the authoritative server by one fixed simulation tick.
Definition ServerSimulation.cpp:273
constexpr std::size_t kServerPeerSessionCapacity
Maximum ENet peers the dedicated server provisions live peer-session storage for.
Definition ServerState.h:35
void createMatchPlayerState(ServerState &state, const uint8_t playerId)
Creates active in-match state for one player seat.
Definition ServerSession.cpp:301
ServerPhase
High-level dedicated-server phase for the current lobby and match flow.
Definition ServerState.h:67
@ Lobby
Accepting players and waiting for match start.
@ StartingMatch
Transitioning accepted players from lobby into the next match.
@ LobbyCountdown
All required players are ready and the lobby countdown is running.
@ InMatch
Authoritative gameplay is active.
@ EndOfMatch
Match has finished and end-of-round presentation/results are active.
constexpr std::size_t kServerInputBufferSize
Input slots retained per active MatchPlayerState.
Definition ServerState.h:40
constexpr int32_t kDefaultServerInputLeadTicks
Default server-side input lead in ticks for authoritative input scheduling.
Definition SimConfig.h:42
constexpr uint8_t kPowerupsPerRound
Number of hidden powerups seeded into each round when enabled.
Definition PowerupConfig.h:44
PowerupType
Supported temporary multiplayer powerup effects.
Definition PowerupConfig.h:22
Tile[tileArrayHeight][tileArrayWidth] TileMap
Read-only view of a runtime tile map (same layout as LevelScene::tiles).
Definition Movement.h:36
constexpr int32_t kDefaultServerSnapshotIntervalTicks
Default server snapshot interval in simulation ticks (1 = every tick / 60 Hz).
Definition SimConfig.h:45
constexpr uint8_t kDefaultPlayerBombRange
Default explosion radius in tiles for newly placed bombs.
Definition SimConfig.h:20
constexpr uint8_t kDefaultPlayerMaxBombs
Default number of simultaneously active bombs a player may own.
Definition SimConfig.h:17
Tile-map cell coordinate used by bomb and powerup state.
Definition ServerState.h:181
Authoritative state for one active bomb in the current match.
Definition ServerState.h:192
uint8_t radius
Snapped from the owner's loadout at placement time.
Definition ServerState.h:197
Bounded reconnect cache for one recently disconnected player seat.
Definition ServerState.h:100
One buffered authoritative input entry for a match player.
Definition ServerState.h:130
bool valid
True while this slot still holds an unconsumed input.
Definition ServerState.h:133
bool seenDirect
Seen as the newest entry in a received batch.
Definition ServerState.h:134
bool seenBuffered
Seen through redundant batch history.
Definition ServerState.h:135
Authoritative in-match state for one accepted player seat.
Definition ServerState.h:146
bool inputTimelineStarted
True once the fixed-delay consume timeline has been armed.
Definition ServerState.h:169
std::array< InputRingEntry, kServerInputBufferSize > inputRing
Indexed by seq % @ref kServerInputBufferSize.
Definition ServerState.h:160
uint8_t lastAppliedButtons
Reused when the next sequence misses its deadline.
Definition ServerState.h:164
Per-dispatch context passed through the typed packet handlers.
Definition ServerState.h:294
std::optional< uint8_t > recordedPlayerId
std::nullopt for pre-handshake traffic.
Definition ServerState.h:299
Live transport/session state for one connected ENet peer.
Definition ServerState.h:115
std::optional< uint8_t > playerId
Populated once Hello is accepted.
Definition ServerState.h:117
Current-session metadata for one accepted player assignment.
Definition ServerState.h:85
Authoritative state for one round-scoped hidden or revealed powerup.
Definition ServerState.h:204
bool revealed
True once the covering brick has been destroyed.
Definition ServerState.h:207
Long-lived authoritative server state shared across receive and simulation paths.
Definition ServerState.h:222
bool powersEnabled
Round powerups are seeded and replicated.
Definition ServerState.h:231
uint32_t currentMatchPlayerMask
Bitmask of player ids participating in the current round start or active round.
Definition ServerState.h:276
std::array< std::optional< DisconnectedPlayerReclaim >, net::kMaxPlayers > disconnectedPlayerReclaims
Last disconnected occupant per player id for bounded lobby-only reconnect reclaim.
Definition ServerState.h:243
std::optional< uint8_t > roundWinnerPlayerId
Winner of the current or most recent round, if any.
Definition ServerState.h:282
std::array< std::optional< PowerupState >, kServerPowerupCapacity > powerups
Hidden and revealed round powerups for the current or next match.
Definition ServerState.h:252
net::NetDiagnostics diag
Diagnostics recorder for this session.
Definition ServerState.h:287
std::array< std::optional< MatchPlayerState >, net::kMaxPlayers > matchPlayers
Stable-address active in-match state keyed by player id.
Definition ServerState.h:248
ServerPhase phase
Current high-level server flow phase.
Definition ServerState.h:226
std::optional< uint32_t > fixedMapSeedOverride
Fixed map seed reused for every round when started with --seed.
Definition ServerState.h:264
std::array< uint8_t, net::kMaxPlayers > playerIdPool
Sorted free-list of available player ids.
Definition ServerState.h:259
std::array< std::optional< BombState >, kServerBombCapacity > bombs
Active bombs for the current round.
Definition ServerState.h:250
ENetHost * host
Non-owning ENet host for this session.
Definition ServerState.h:225
std::array< std::optional< PlayerSlot >, net::kMaxPlayers > playerSlots
Active accepted-player metadata keyed by player id. See PlayerSlot.
Definition ServerState.h:241
uint32_t serverTick
Authoritative simulation tick advanced by simulateServerTick().
Definition ServerState.h:227
uint32_t currentLobbyCountdownPlayerMask
Bitmask of players currently participating in the lobby countdown.
Definition ServerState.h:272
uint32_t currentMatchId
Current match identifier, or 0 while idle in the lobby.
Definition ServerState.h:269
std::array< std::optional< PeerSession >, kServerPeerSessionCapacity > peerSessions
Stable-address live peer sessions indexed by ENet incoming peer id.
Definition ServerState.h:236
sim::TileMap tiles
Collision map shared by all server-side movement steps.
Definition ServerState.h:255
Tile-space Q8 position representing the CENTER of the entity.
Definition Movement.h:30