group2 0.1.0
CSE 125 Group 2
Loading...
Searching...
No Matches
Client.hpp
Go to the documentation of this file.
1
3
4#pragma once
5
19#include "network/ShotDebugReport.hpp" // PR-20: shared wire-format + runtime capture struct.
20#include "network/ShotEvent.hpp"
26
27#include <SDL3/SDL_stdinc.h>
28
29#include <SDL3_net/SDL_net.h>
30#include <array>
31#include <atomic>
32#include <cstdint>
33#include <deque>
34#include <entt/entt.hpp>
35#include <mutex>
36#include <optional>
37#include <random>
38#include <span>
39#include <string_view>
40#include <thread>
41#include <utility>
42
45{
46 float rttMs = 0.0f;
47 float avgRttMs = 0.0f;
48 uint64_t bytesRecvTotal = 0;
49 uint64_t bytesSentTotal = 0;
50 float recvBytesPerSec = 0.0f;
51 float sendBytesPerSec = 0.0f;
52 uint32_t registryUpdateSize = 0;
53 float registryUpdatesPerSec = 0.0f;
54};
55
66
68class Client
69{
70public:
73 using SnapshotApplyCallback = std::function<bool(std::uint32_t snapshotTick,
74 const std::uint8_t* bytes,
75 Uint32 size,
76 Uint64 captureNs,
77 std::uint32_t& ackedTick)>;
79 using RawParticleEventCallback = std::function<void(const NetParticleEvent& evt)>;
80 using MatchStateUpdateFn = std::function<void(const MatchStatePacket&)>;
81 using KillEventCallback = std::function<void(const NetKillEvent&)>;
82 using TextChatCallback = std::function<void(const net::chat::ServerTextChat&)>;
84 using RosterEventCallback = std::function<void(const PlayerRosterEvent&)>;
85 using VoiceFrameCallback = std::function<void(const net::voice::ServerVoiceFrame&)>;
91 using ShotDebugCallback = std::function<void(const net::shotdebug::ShotDebugCapture&)>;
92
94 using LobbyUpdateCallback = std::function<void(const LobbyUpdateEvent& update)>;
96 using LobbyStateCallback = std::function<void(const std::vector<LobbyPlayer>& players, ClientId localId)>;
97 using MatchConfigCallback = std::function<void(const MatchConfig& config)>;
98
107 ConnectError init(const char* addr,
108 Uint16 port,
109 const TransportConfig& transport = {},
110 int timeoutMs = -1,
111 const std::optional<net::UdpSessionTransport::RelayConfig>& relay = std::nullopt,
112 const std::optional<net::UdpSessionTransport::PunchAssist>& punch = std::nullopt);
113
115 void shutdown();
116
118 bool isConnected();
119
124 bool send(const void* data, uint32_t size);
125
136 bool sendInputSnapshot(const InputSnapshot& snap);
137
139 void resetInputHistory();
140
148 bool sendShotIntent(std::uint32_t shotInputTick, std::uint16_t targetClientId, const AnimSnapshot& targetAnim);
149
151 bool sendChatMessage(std::string_view message);
152
154 bool sendPhysicsDiagRecording(bool enabled);
155
157 bool sendVoiceFrame(std::uint16_t sequence, std::uint8_t frameMs, std::span<const std::uint8_t> opus);
158
160 bool sendPlayerReady(bool ready);
161
163 bool sendStartMatch();
164
167
169 bool sendMatchConfig(const MatchConfig& config);
170
176 bool sendDiscoverySettings(const DiscoverySettings& settings);
177
179 bool sendServerShutdown();
180
182 void sendPing();
183
185 void updateStats(float dt);
186
188 {
189 snapshotApplyFn_ = std::move(fn);
190 }
192 {
193 rawParticleEventFn_ = std::move(fn);
194 }
198 void onKillEvent(KillEventCallback fn) { killEventFn_ = std::move(fn); }
199 void onTextChat(TextChatCallback fn) { textChatFn_ = std::move(fn); }
202 void onVoiceFrame(VoiceFrameCallback fn) { voiceFrameFn_ = std::move(fn); }
206 {
207 lobbyUpdateFn_ = std::move(fn);
208 }
210 {
211 lobbyStateFn_ = std::move(fn);
212 }
214 {
215 matchConfigFn_ = std::move(fn);
216 }
217
220 bool poll();
221
223 const NetworkStats& getNetStats() const { return stats; }
224
226 std::optional<MatchStatePacket> getLatestMatchState() const { return latestMatchState_; }
227
229 std::optional<MatchConfig> getLatestMatchConfig() const { return latestMatchConfig_; }
230
232 std::optional<std::pair<std::vector<LobbyPlayer>, ClientId>> getLatestLobbyState() const;
233
235 std::optional<std::string> getLatestServerName() const { return latestServerName_; }
236
245 [[nodiscard]] uint32_t getServerAckedClientTick() const noexcept { return serverAckedClientTick_; }
246
252 [[nodiscard]] bool consumeSnapshotApplied() noexcept
253 {
254 const bool was = snapshotAppliedFlag_;
255 snapshotAppliedFlag_ = false;
256 return was;
257 }
258
279 [[nodiscard]] float getSnapshotAlpha() const;
280
283 [[nodiscard]] std::optional<entt::entity> getServerLocalPlayerEntity() const { return localPlayerEntity; }
284
304 [[nodiscard]] Uint64 getInterpolationRenderTimeNs() const;
305
310 [[nodiscard]] Uint64 getSnapshotIntervalNs() const;
311
346
348 void recordInterpolationSamples(Registry& registry, Uint64 captureNs);
349
355 static constexpr size_t k_inputRedundancy = 5;
356
377 void setSimulatedLatencyMs(int totalMs) noexcept;
378
380 [[nodiscard]] int getSimulatedLatencyMs() const noexcept
381 {
382 return simulatedLatencyMs_.load(std::memory_order_relaxed);
383 }
384
403 void setSimulatedLossPercent(int percent) noexcept;
404
406 [[nodiscard]] int getSimulatedLossPercent() const noexcept
407 {
408 return simulatedLossPercent_.load(std::memory_order_relaxed);
409 }
410
411 bool sendGameplayReady();
412
413private:
415 NET_Address* serverAddr = nullptr;
427 std::optional<entt::entity> localPlayerEntity;
428 std::optional<MatchStatePacket>
430 std::optional<MatchConfig> latestMatchConfig_;
431 std::optional<std::vector<LobbyPlayer>> latestLobbyPlayers_;
432 std::optional<ClientId> latestLobbyLocalId_;
433 std::optional<std::string> latestServerName_;
434
435 // ── PR-10 + PR-14 (server-perf): snapshot delta encoding state ────
436 //
437 // `keyframePayload_` holds the most-recent FULL snapshot's raw
438 // entt-serialized bytes (no PacketType prefix, no tick), and
439 // `keyframeTick_` is the tick that snapshot was sent at.
440 //
441 // PR-14 (loss resilience): both fields update *only* on FULL
442 // arrival. DELTA packets reconstruct the current frame's bytes
443 // by applying their patch on top of the keyframe and feed the
444 // reconstructed bytes into the Loader, but do NOT replace the
445 // saved keyframe. Pre-PR-14, every DELTA replaced the saved
446 // baseline with the just-reconstructed bytes — which meant a
447 // single dropped DELTA cascaded into all subsequent DELTAs in the
448 // same keyframe window dropping silently (their `fromTick` no
449 // longer matched the client's stored `lastSnapshotTick_`). Now
450 // every DELTA in a window is independently decodable against the
451 // shared keyframe, so individual packet drops only cost that one
452 // frame's state.
453 //
454 // If `fromTick` on a DELTA doesn't match `keyframeTick_` the
455 // packet is dropped — happens when a FULL keyframe was lost or
456 // hasn't arrived yet. The next periodic full keyframe (every 8
457 // snapshots ≈ 62 ms at 128 Hz) re-syncs us.
458 std::vector<uint8_t> keyframePayload_;
459 std::uint32_t keyframeTick_ = 0;
460
462
463 // Bandwidth tracking — accumulated between updateStats() calls.
464 uint64_t bytesSentWindow = 0;
465 uint64_t bytesRecvWindow = 0;
469 float statsAccumulator = 0.0f;
470
471 // Redundant input ring — see k_inputRedundancy and sendInputSnapshot().
472 // Stores the last N stamped InputSnapshots in chronological order so each
473 // outbound INPUT packet can include them all (server dedups by tick).
474 std::array<InputSnapshot, k_inputRedundancy> inputRing_{};
475 size_t inputRingHead_ = 0;
476 size_t inputRingCount_ = 0;
477
478 // ── Stage 3c: dedicated network thread ────────────────────────────────
479 //
480 // Symmetric to the server's stage 3b. The network thread continuously
481 // (a) pumps the kernel receive buffer into msgStream's recvBuf and
482 // (b) drains the outbound queue to the socket. The game thread keeps
483 // calling sendInputSnapshot / sendPing / poll() — those now
484 // touch the queue + recvBuf under stateMutex_ rather than doing
485 // syscalls inline. The win is that a render-frame stutter on the game
486 // thread no longer causes the kernel buffer to back up.
488 std::mutex stateMutex_;
489 std::thread networkThread_;
490 std::atomic<bool> shouldStop_{false};
491
495 std::atomic<bool> socketDead_{false};
496
497 // ── Phase 5a: snapshot-interval interpolation timing ──────────────────
498 //
499 // Updated whenever dispatchMessage applies an UPDATE_REGISTRY. The
500 // renderer reads getSnapshotAlpha() instead of the physics-tick alpha
501 // so motion stays smooth at the much-coarser snapshot rate. Both fields
502 // are 0 before any snapshot has been applied; getSnapshotAlpha returns
503 // 1.0 in that case so first frame draws the snapped position.
506
507 // ── PR-11: render-delay interpolation ────────────────────────────────
508 //
509 // `interpDelaySnapshots_` is read once at init() from the
510 // GROUP2_CLIENT_INTERP_DELAY_SNAPSHOTS env var (default 2). 0 disables
511 // the buffered render-delay path entirely; non-local entities
512 // fall back to the Phase-5a (prev, cur, alpha) lerp. Higher values
513 // smooth more loss but make remote entities visibly behind server
514 // truth. Source engine ships 2 (62.5 ms at 32 Hz) — that's our
515 // default and matches Valorant / Fortnite cadence.
516 //
517 // EMA of snapshot apply intervals. `prevSnapshotApplyNs_` and
518 // `lastSnapshotApplyNs_` already give a single most-recent interval;
519 // the EMA smooths burst arrivals so the render-delay computation
520 // doesn't wobble when packets arrive bunched. Snapshot rate doesn't
521 // change during a session, so a single-pole IIR with α=0.25 is
522 // ample. Initial value matches the design's 32 Hz snapshot rate.
523 // PR-13: 128 Hz default snapshot rate (AAA-pro cadence). EMA
524 // self-corrects once two snapshots have arrived if the actual
525 // rate differs (e.g. legacy server running at 32 Hz from a
526 // pre-PR-13 config.toml). The two-snapshot warmup window is
527 // ~16 ms at 128 Hz — fast enough that the initial value barely
528 // matters in practice.
529 static constexpr Uint64 k_defaultSnapshotIntervalNs = 1'000'000'000ULL / 128ULL;
530
531 // PR-19: re-enabled default = 2 snapshots after `Client::
532 // applyInterpolatedTransforms` started overwriting Position +
533 // InputSnapshot.yaw in place every frame. Now ALL visual
534 // consumers (renderer, tracers, ribbon trails, smoke emitters,
535 // beam endpoints, sfx) read from a single source of truth —
536 // `pos.value`, freshly written each frame to the interpolated
537 // value — so there's no more 6-unit body-vs-tracer separation
538 // that PR-16 was the emergency hotfix for.
539 //
540 // PR-16's history (kept for posterity): pre-PR-19, PR-11 wired
541 // `entity_interpolation::sample()` into 3 specific Game.cpp
542 // render sites only, missing TracerEffect / RibbonTrail /
543 // SmokeEffect / BeamState / sfx. PR-16 default-flipped this to
544 // 0 to disable the misaligned interp until PR-19's unified
545 // approach landed. PR-17 (FragmentReassembler stuck-state)
546 // turned out to be the bigger source of "models in wrong
547 // locations" — once that was fixed and PR-19 unifies the read
548 // path, default-on is safe again.
549 //
550 // To disable: set `GROUP2_CLIENT_INTERP_DELAY_SNAPSHOTS=0`.
553
554 // ── Phase 5b: prediction reconciliation hand-off ──────────────────────
555 //
556 // Updated by dispatchMessage on every UPDATE_REGISTRY apply. The game
557 // thread reads getServerAckedClientTick() + consumeSnapshotApplied() to
558 // know when and from which tick to replay client-stored inputs.
561
562 // ── Phase 3d: UDP sidecar ─────────────────────────────────────────────
563 //
564 // Bound during init() to any free local port. Server's address is
565 // resolved from the same hostname/port we connected over TCP. We
566 // stamp every outbound UDP datagram with the connectionId the
567 // server gave us in the ASSIGN_CLIENT_ID packet so it can match
568 // datagrams to our TCP-established Connection. Until that arrives
569 // we fall back to TCP for everything (connectionId == 0).
571 bool usingUdpSession_ = false;
575 std::uint64_t connectionId_ = 0;
576 uint16_t udpInputSequence_ = 0;
577 std::uint16_t chatClientSeq_ = 0;
578
584 std::vector<std::vector<uint8_t>> udpRecvQueue_;
585
592
600 std::uint32_t reliableHighestSeen_ = 0;
602 bool reliableHasAny_ = false;
603
607 bool acceptReliableSequence(std::uint32_t seq);
608
609 // ── Phase 6 testing: latency simulator ────────────────────────────────
610 //
611 // Two FIFO queues — outbound packets that haven't reached the kernel
612 // socket yet, and inbound payloads that haven't been delivered to the
613 // game thread's dispatch queue yet. Both are drained at the top of
614 // each `networkLoop` cycle: any entry whose target counter has passed
615 // is sent (or enqueued for dispatch). Both share `stateMutex_` because
616 // the existing send/receive paths already hold it; piggy-backing
617 // avoids a second mutex.
618 //
619 // Sized to grow with traffic — typical worst case is 200 ms × 128 Hz
620 // INPUT × 1 client + ~32 Hz inbound snapshot stream ≈ 30 entries.
621
624 std::atomic<int> simulatedLatencyMs_{0};
625
629 std::atomic<int> simulatedLossPercent_{0};
630
636 std::mt19937 simLossRng_{};
637
641
644 {
647 std::vector<uint8_t> payload;
648 std::size_t totalBytes;
649 };
650 std::deque<DelayedOutbound> simLatOutbound_;
651
654 {
656 std::vector<uint8_t> payload;
657 };
658 std::deque<DelayedInbound> simLatInbound_;
659
666 bool sendUdpDelayed(net::PacketHeader hdr, const void* data, int len);
667
671 void recvUdpDelayed(std::vector<uint8_t>&& payload);
672
674 void networkLoop();
675
678 void dispatchMessage(const uint8_t* data, Uint32 size);
679
681 bool applySnapshot(std::uint32_t snapshotTick, const std::uint8_t* bytes, Uint32 size, Uint32 wireSize);
682};
PR-27 — per-entity animation state snapshot, decoupled from CharacterAnimator.
Bounded text-chat packet helpers shared by client, server, and tests.
ConnectError
Definition Client.hpp:57
@ ResolveFailed
Definition Client.hpp:59
@ ResolveTimedOut
Definition Client.hpp:60
@ ConnectFailed
Definition Client.hpp:63
@ LobbyFull
Definition Client.hpp:64
@ ConnectTimedOut
Definition Client.hpp:62
@ CreateClientFailed
Definition Client.hpp:61
@ None
Definition Client.hpp:58
Runtime host-controlled discovery advertisement settings.
Per-connection assembly buffer for fragmented UDP packets.
Per-tick player input snapshot for networking and prediction.
Shared lobby data types exchanged between server and clients.
Shared definitions for match status and state synchronization between server and clients.
Length-prefixed message framing layer over a TCP stream socket.
Structure of kill event broadcasted from server to clients.
Network configuration loaded from config.toml at startup.
Per-client outbound message queue with replace-on-stale semantics.
Serialize and deserialize the entt ECS registry for network replication.
Shared ECS registry type alias for the game engine.
entt::registry Registry
Shared ECS registry type alias.
Definition Registry.hpp:11
Wire-format types for the PR-20 lag-comp shot debug visualizer.
Wire-format particle effect event broadcast from server to all clients.
Thin wrapper over SDL3_net's NET_DatagramSocket.
UDP-first session transport with handshake, reliability, and relay routing.
Bounded Opus voice-frame packet helpers.
TCP stream client — sends input to the server and receives state updates.
Definition Client.hpp:69
std::deque< DelayedInbound > simLatInbound_
Definition Client.hpp:658
size_t inputRingHead_
Next write index, wraps mod k_inputRedundancy.
Definition Client.hpp:475
static constexpr size_t k_inputRedundancy
Number of recent inputs included in each INPUT packet for redundancy.
Definition Client.hpp:355
VoiceFrameCallback voiceFrameFn_
Called for proximity-routed Opus voice frames.
Definition Client.hpp:422
net::UdpSessionTransport session_
Definition Client.hpp:572
void onSnapshotApply(SnapshotApplyCallback fn)
Register the snapshot-apply callback; must be set before the first poll().
Definition Client.hpp:187
net::UdpEndpoint udpEndpoint_
Definition Client.hpp:573
Uint64 snapshotIntervalEmaNs_
Definition Client.hpp:552
std::vector< std::vector< uint8_t > > udpRecvQueue_
UDP-received payloads waiting for the game thread to dispatch.
Definition Client.hpp:584
void sendPing()
Send a PING packet to the server for RTT measurement.
Definition Client.cpp:329
std::function< bool(std::uint32_t snapshotTick, const std::uint8_t *bytes, Uint32 size, Uint64 captureNs, std::uint32_t &ackedTick)> SnapshotApplyCallback
Called by Client to apply a raw snapshot; the registry-owning caller performs the actual load.
Definition Client.hpp:73
std::function< void(const std::vector< LobbyPlayer > &players, ClientId localId)> LobbyStateCallback
Fired once on join with the full lobby snapshot and this client's assigned ID.
Definition Client.hpp:96
std::deque< DelayedOutbound > simLatOutbound_
Definition Client.hpp:650
bool consumeSnapshotApplied() noexcept
Whether a snapshot was applied since the last call to consumeSnapshotApplied().
Definition Client.hpp:252
std::optional< ClientId > latestLobbyLocalId_
This client's ID as reported in the LOBBY_STATE packet.
Definition Client.hpp:432
std::mutex stateMutex_
Definition Client.hpp:488
bool shouldDropPacketLocked()
Roll the loss RNG.
Definition Client.cpp:883
NET_Address * serverAddr
Resolved server address.
Definition Client.hpp:415
std::function< void(const LobbyUpdateEvent &update)> LobbyUpdateCallback
Fired for each incremental lobby roster update broadcast from the server.
Definition Client.hpp:94
MatchConfigCallback matchConfigFn_
Called whenever a MATCH_CONFIG packet is received.
Definition Client.hpp:426
bool sendVoiceFrame(std::uint16_t sequence, std::uint8_t frameMs, std::span< const std::uint8_t > opus)
Send one Opus-encoded voice frame. Voice rides unreliable sequenced UDP.
Definition Client.cpp:580
std::uint64_t connectionId_
Definition Client.hpp:575
void onMatchConfig(MatchConfigCallback fn)
Register the match-config update callback.
Definition Client.hpp:213
uint64_t bytesSentWindow
Definition Client.hpp:464
std::thread networkThread_
Definition Client.hpp:489
void onLobbyUpdate(LobbyUpdateCallback fn)
Register the incremental lobby-update callback.
Definition Client.hpp:205
std::optional< MatchConfig > getLatestMatchConfig() const
Return the latest match configuration received from the server, if any.
Definition Client.hpp:229
uint16_t udpInputSequence_
Per-channel sequence for INPUT datagrams.
Definition Client.hpp:576
uint32_t registryUpdatesWindow
Definition Client.hpp:468
bool snapshotAppliedFlag_
Definition Client.hpp:560
bool sendChatMessage(std::string_view message)
Send an all-chat message to the authoritative server.
Definition Client.cpp:563
KillEventCallback killEventFn_
Called for each replicated kill event from server.
Definition Client.hpp:419
std::function< void(const MatchConfig &config)> MatchConfigCallback
Definition Client.hpp:97
LobbyUpdateCallback lobbyUpdateFn_
Called for each lobby update received from server.
Definition Client.hpp:424
std::uint16_t chatClientSeq_
Definition Client.hpp:577
void shutdown()
Close the socket and release the resolved address.
Definition Client.cpp:250
std::optional< entt::entity > getServerLocalPlayerEntity() const
Server-assigned local-player entity before continuous_loader mapping.
Definition Client.hpp:283
void updateStats(float dt)
Update bandwidth stats. Call once per frame with the frame delta time.
Definition Client.cpp:375
bool usingUdpSession_
Definition Client.hpp:571
bool poll()
Receive and process one pending message.
Definition Client.cpp:1524
std::optional< std::vector< LobbyPlayer > > latestLobbyPlayers_
Most-recent lobby roster received from the server.
Definition Client.hpp:431
int interpDelaySnapshots_
Definition Client.hpp:551
std::array< InputSnapshot, k_inputRedundancy > inputRing_
Definition Client.hpp:474
void recvUdpDelayed(std::vector< uint8_t > &&payload)
Enqueue an assembled UDP message into udpRecvQueue_ immediately if the simulator is off,...
Definition Client.cpp:930
std::function< void(const net::shotdebug::ShotDebugCapture &)> ShotDebugCallback
PR-20: callback for SHOT_DEBUG_REPORT.
Definition Client.hpp:91
const NetworkStats & getNetStats() const
Access current network statistics.
Definition Client.hpp:223
bool sendServerShutdown()
Request server shutdown. The server accepts this only from the current host.
Definition Client.cpp:629
std::uint32_t keyframeTick_
Definition Client.hpp:459
void setSimulatedLossPercent(int percent) noexcept
Phase 6 testing: simulate UDP packet loss.
Definition Client.cpp:874
uint64_t reliableSeenBitmask_
Definition Client.hpp:601
void resetInputHistory()
Clear redundant input history at the start of a new local match instance.
Definition Client.cpp:506
bool sendShotIntent(std::uint32_t shotInputTick, std::uint16_t targetClientId, const AnimSnapshot &targetAnim)
PR-27 (netsync): send a SHOT_INTENT packet describing the client's view of the target's animation sta...
Definition Client.cpp:513
net::UdpEndpointAddr serverUdpAddr_
Definition Client.hpp:574
net::FragmentReassembler unreliableReassembler_
Phase 3d-4: reassembly buffer for fragmented snapshot datagrams on the Unreliable channel.
Definition Client.hpp:591
float getSnapshotAlpha() const
Render-time interpolation alpha based on snapshot timing.
Definition Client.cpp:683
Uint64 getInterpolationRenderTimeNs() const
Render time the renderer should display non-local entities at.
Definition Client.cpp:839
void recordInterpolationSamples(Registry &registry, Uint64 captureNs)
Record interpolation samples after the caller has applied a snapshot.
Definition Client.cpp:799
void onLobbyState(LobbyStateCallback fn)
Register the full lobby-snapshot callback, fired once on join.
Definition Client.hpp:209
Uint64 prevSnapshotApplyNs_
Definition Client.hpp:505
void onMatchStateUpdate(MatchStateUpdateFn fn)
Register the match-state update callback, fired on every MATCH_STATE packet.
Definition Client.hpp:196
RosterEventCallback rosterEventFn_
Called for mid-match player join/leave updates.
Definition Client.hpp:421
void onShotDebugReport(ShotDebugCallback fn)
Register the shot-debug callback (PR-20); fired for each SHOT_DEBUG_REPORT.
Definition Client.hpp:204
void networkLoop()
Network-thread main loop body.
Definition Client.cpp:948
bool sendMatchConfig(const MatchConfig &config)
Send an updated match configuration to the server (host-only).
Definition Client.cpp:611
void onRosterEvent(RosterEventCallback fn)
Register the roster-event callback, fired for each mid-match join/leave.
Definition Client.hpp:201
float statsAccumulator
Definition Client.hpp:469
std::optional< std::string > latestServerName_
Server display name reported by the latest LOBBY_STATE packet.
Definition Client.hpp:433
bool sendInputSnapshot(const InputSnapshot &snap)
Push the latest input into the redundant ring and send to the server.
Definition Client.cpp:389
TransportConfig transportConfig_
Definition Client.hpp:570
void onTextChat(TextChatCallback fn)
Definition Client.hpp:199
std::uint32_t reliableHighestSeen_
Phase 3d-5: sliding-window bitset for ReliableOrdered channel dedup.
Definition Client.hpp:600
std::function< void(const PlayerRosterEvent &)> RosterEventCallback
Fired for server-authored mid-match join/leave notifications.
Definition Client.hpp:84
bool sendCancelStartMatch()
Send a CANCEL_START_MATCH packet to the server (host-only).
Definition Client.cpp:605
std::function< void(const NetKillEvent &)> KillEventCallback
Definition Client.hpp:81
std::function< void(const net::voice::ServerVoiceFrame &)> VoiceFrameCallback
Definition Client.hpp:85
ShotDebugCallback shotDebugFn_
PR-20: called for each SHOT_DEBUG_REPORT from server.
Definition Client.hpp:423
uint32_t serverAckedClientTick_
Definition Client.hpp:559
std::atomic< int > simulatedLossPercent_
Per-direction independent UDP-drop probability (slider value, 0–100).
Definition Client.hpp:629
void dispatchMessage(const uint8_t *data, Uint32 size)
Decode and dispatch a single complete framed message.
Definition Client.cpp:1156
bool sendPhysicsDiagRecording(bool enabled)
Ask the server to start/stop authoritative physics CSV recording.
Definition Client.cpp:571
bool applySnapshot(std::uint32_t snapshotTick, const std::uint8_t *bytes, Uint32 size, Uint32 wireSize)
Invoke snapshotApplyFn_ with raw snapshot bytes; updates delta-decode state on success.
Definition Client.cpp:1129
Uint64 lastSnapshotApplyNs_
Definition Client.hpp:504
std::vector< uint8_t > keyframePayload_
Definition Client.hpp:458
bool isConnected()
True while a server connection is currently owned by this client.
Definition Client.cpp:286
uint64_t bytesRecvWindow
Definition Client.hpp:465
void onKillEvent(KillEventCallback fn)
Register the kill-event callback, fired for each replicated kill from the server.
Definition Client.hpp:198
bool sendStartMatch()
Send a START_MATCH packet to the server (host-only).
Definition Client.cpp:599
std::function< void(const NetParticleEvent &evt)> RawParticleEventCallback
Called for each replicated particle event before entity mapping; caller is responsible for mapping.
Definition Client.hpp:79
uint32_t getServerAckedClientTick() const noexcept
Latest server-acked client predict tick.
Definition Client.hpp:245
std::atomic< bool > socketDead_
Latched-true once the network thread observes a socket error.
Definition Client.hpp:495
static constexpr Uint64 k_defaultSnapshotIntervalNs
Definition Client.hpp:529
int getSimulatedLatencyMs() const noexcept
Get the currently-effective simulated total RTT.
Definition Client.hpp:380
size_t inputRingCount_
Valid entries in ring; saturates at k_inputRedundancy.
Definition Client.hpp:476
uint64_t udpSessionLastBytesSent_
Definition Client.hpp:466
RawParticleEventCallback rawParticleEventFn_
Called for unmapped replicated particle events.
Definition Client.hpp:417
void onVoiceFrame(VoiceFrameCallback fn)
Definition Client.hpp:202
uint64_t udpSessionLastBytesRecv_
Definition Client.hpp:467
bool send(const void *data, uint32_t size)
Send a raw message to the server.
Definition Client.cpp:305
int getSimulatedLossPercent() const noexcept
Get the currently-effective simulated packet loss %.
Definition Client.hpp:406
std::atomic< int > simulatedLatencyMs_
Total simulated RTT in ms (slider value, 0–200).
Definition Client.hpp:624
MatchStateUpdateFn matchStateUpdateFn_
Called whenever a MATCH_STATE packet is received.
Definition Client.hpp:418
void onRawParticleEvent(RawParticleEventCallback fn)
Register the raw particle-event callback.
Definition Client.hpp:191
bool acceptReliableSequence(std::uint32_t seq)
Sliding-window dedup helper.
Definition Client.cpp:643
std::optional< MatchStatePacket > latestMatchState_
Most-recent MATCH_STATE packet; populated by dispatchMessage.
Definition Client.hpp:429
void applyInterpolatedTransforms(Registry &registry)
PR-19: overwrite Position.value (and InputSnapshot.yaw) for every non-local entity with an Interpolat...
Definition Client.cpp:713
SnapshotApplyCallback snapshotApplyFn_
Applies snapshot bytes in the registry-owning caller.
Definition Client.hpp:416
MessageStream msgStream
Framed message stream for server communication.
Definition Client.hpp:414
NetworkStats stats
Live network metrics.
Definition Client.hpp:461
std::optional< std::pair< std::vector< LobbyPlayer >, ClientId > > getLatestLobbyState() const
Return the latest lobby roster received from the server, if any.
Definition Client.cpp:635
std::function< void(const MatchStatePacket &)> MatchStateUpdateFn
Definition Client.hpp:80
ConnectError init(const char *addr, Uint16 port, const TransportConfig &transport={}, int timeoutMs=-1, const std::optional< net::UdpSessionTransport::RelayConfig > &relay=std::nullopt, const std::optional< net::UdpSessionTransport::PunchAssist > &punch=std::nullopt)
Create the TCP socket and connect to the server.
Definition Client.cpp:46
std::atomic< bool > shouldStop_
Definition Client.hpp:490
std::optional< MatchConfig > latestMatchConfig_
Most-recent MATCH_CONFIG packet; populated by dispatchMessage.
Definition Client.hpp:430
std::optional< MatchStatePacket > getLatestMatchState() const
Return the latest match state packet received from the server, if any.
Definition Client.hpp:226
TextChatCallback textChatFn_
Called for server-broadcast all-chat messages.
Definition Client.hpp:420
bool sendUdpDelayed(net::PacketHeader hdr, const void *data, int len)
Send a UDP datagram immediately if the latency simulator is off, otherwise queue it for delayed send.
Definition Client.cpp:896
bool reliableHasAny_
False until the first reliable event arrives.
Definition Client.hpp:602
bool sendGameplayReady()
Definition Client.cpp:1577
std::optional< entt::entity > localPlayerEntity
The local player's entity, once assigned by the server.
Definition Client.hpp:427
void setSimulatedLatencyMs(int totalMs) noexcept
Phase 6 testing: simulate added round-trip latency.
Definition Client.cpp:861
std::function< void(const net::chat::ServerTextChat &)> TextChatCallback
Definition Client.hpp:82
OutboundQueue outbound_
Definition Client.hpp:487
LobbyStateCallback lobbyStateFn_
Called once on join with the full lobby snapshot.
Definition Client.hpp:425
bool sendPlayerReady(bool ready)
Send a PLAYER_READY or PLAYER_UNREADY packet to the server.
Definition Client.cpp:593
std::optional< std::string > getLatestServerName() const
Return the latest server display name received from the server, if any.
Definition Client.hpp:235
std::mt19937 simLossRng_
PRNG for the loss simulator.
Definition Client.hpp:636
Uint64 getSnapshotIntervalNs() const
Approximate snapshot interval in nanoseconds.
Definition Client.cpp:708
bool sendDiscoverySettings(const DiscoverySettings &settings)
Send updated discovery advertisement settings to the server.
Definition Client.cpp:619
Length-prefixed framing layer over a TCP stream socket.
Definition MessageStream.hpp:29
Per-connection outbound message queue.
Definition OutboundQueue.hpp:85
Definition FragmentReassembler.hpp:33
Wraps a NET_DatagramSocket with header-prefixed I/O.
Definition UdpEndpoint.hpp:109
Definition UdpSessionTransport.hpp:26
Snapshot of an entity's full animation state at one instant.
Definition AnimSnapshot.hpp:73
Associates an entity with a connected network client.
Definition ClientId.hpp:10
One inbound payload queued for delayed dispatch.
Definition Client.hpp:654
Uint64 deliverAtCounter
Performance counter at which to enqueue.
Definition Client.hpp:655
std::vector< uint8_t > payload
Already-assembled message ([PacketType][rest]).
Definition Client.hpp:656
One outbound UDP datagram queued for delayed send.
Definition Client.hpp:644
std::vector< uint8_t > payload
Datagram payload bytes.
Definition Client.hpp:647
Uint64 sendAtCounter
Performance counter at which to send.
Definition Client.hpp:645
net::PacketHeader header
Caller-supplied header (passed through verbatim).
Definition Client.hpp:646
std::size_t totalBytes
For deferred bandwidth accounting.
Definition Client.hpp:648
Host-managed discovery visibility flags.
Definition DiscoverySettings.hpp:11
One tick of player input, stamped with the tick it was sampled on.
Definition InputSnapshot.hpp:17
Incremental lobby change event broadcast to all connected clients.
Definition LobbyStatus.hpp:34
Definition MatchConfig.hpp:4
Definition MatchStatus.hpp:17
Event representing a player kill, sent from server to client for kill feed updates.
Definition NetKillEvent.hpp:12
Wire-format particle event broadcast from server to all clients.
Definition ShotEvent.hpp:28
Live network statistics updated each frame.
Definition Client.hpp:45
float registryUpdatesPerSec
Registry updates received per second.
Definition Client.hpp:53
float avgRttMs
Exponential moving average RTT (ms).
Definition Client.hpp:47
uint32_t registryUpdateSize
Last registry update payload size (bytes).
Definition Client.hpp:52
float rttMs
Latest round-trip time (ms).
Definition Client.hpp:46
uint64_t bytesSentTotal
Total bytes sent since connection.
Definition Client.hpp:49
float recvBytesPerSec
Receive bandwidth (bytes/sec, smoothed).
Definition Client.hpp:50
float sendBytesPerSec
Send bandwidth (bytes/sec, smoothed).
Definition Client.hpp:51
uint64_t bytesRecvTotal
Total bytes received since connection.
Definition Client.hpp:48
Server-authored join/leave notification for in-progress matches.
Definition RosterEvent.hpp:20
Phase 3d: per-feature toggles for the UDP transport rollout.
Definition NetworkConfig.hpp:63
36-byte header at the start of every UDP datagram.
Definition PacketHeader.hpp:71
A UDP datagram address (server's view of a remote peer).
Definition UdpEndpoint.hpp:49
Definition ChatProtocol.hpp:27
Server-side runtime capture of one shot's debug data, produced by WeaponSystem::handleFire and consum...
Definition ShotDebugReport.hpp:111
Definition VoiceProtocol.hpp:36