11#include "ecs/component/core/transform.h"
12#include "ecs/component/physics/rigidbody.h"
13#include "ecs/entity.h"
14#include "net/prediction/command.h"
15#include "net/prediction/interpolation.h"
16#include "net/prediction/pacing.h"
17#include "net/transport/connection.h"
18#include "net/wire/bit_stream.h"
19#include "net/wire/protocol.h"
21namespace Vkm::Engine {
34constexpr uint32_t NET_SPAWN_BUILDS_PER_FRAME = 8;
44 explicit NetClient(
NetCore& core);
47 NetClient(
const NetClient& other) =
delete;
48 NetClient& operator=(
const NetClient& other) =
delete;
50 NetClient(NetClient && other) =
delete;
51 NetClient& operator=(NetClient && other) =
delete;
60 void advance(
float seconds);
79 void lease(
const std::vector<EntityId>& entities);
90 void beginReplayTick() { m_prediction.replaying =
true; }
95 void interpolate(
Scene& scene,
float deltaTime);
106 std::string describe()
const;
109 PlayerId localPlayer()
const {
return m_localPlayer; }
110 EntityId localEntity()
const {
return m_localEntity; }
113 bool isPlaying()
const {
return m_localPlayer != NO_PLAYER; }
115 float roundTrip()
const {
return m_connection ? m_connection->roundTrip() : 0.0f; }
117 size_t leaseCount()
const {
return m_prediction.leases.size(); }
119 const std::vector<InputCommand>& replayCommands()
const {
return m_prediction.replay; }
121 bool replaying()
const {
return m_prediction.replaying; }
123 float predictionError()
const {
return m_prediction.error; }
125 float renderDelay()
const {
return m_interpolation.behindTicks(); }
127 float pacing()
const {
return m_prediction.pacing.scale(); }
135 glm::vec3 position{0.0f};
153 struct DrawCorrection {
169 bool hasBody =
false;
178 std::vector<Predicted> predicted;
180 std::vector<InputCommand> unacknowledged;
181 std::vector<InputCommand> replay;
182 bool replaying =
false;
194 std::vector<Lease> leases;
195 std::vector<EntityId> acquired;
196 std::vector<EntityId> released;
199 std::vector<Held> held;
200 std::vector<DrawCorrection> corrections;
202 bool warnedNoReplay =
false;
204 void clear() { *
this = Prediction{}; }
213 glm::vec3 drawn{0.0f};
217 bool onWelcome(Scene& scene, BitReader& reader);
218 bool onRefuse(BitReader& reader);
220 void onSnapshot(Scene& scene, BitReader& reader);
232 void holdPredicted(Scene& scene, std::vector<DrawnFrom>& takenFrom);
244 void buildSpawned(Scene& scene, ResourceManager& resources);
257 void buildInto(Scene& scene, ResourceManager& resources, EntityId root,
const NetSpawn& spawn);
268 void reconcile(Scene& scene, uint32_t confirmedTick);
279 void restoreHeld(Scene& scene);
280 void correctDraw(EntityId entity,
const glm::vec3& drawn,
const glm::vec3& simulated);
281 void offsetDrawn(Scene& scene, EntityId entity,
const glm::vec3& by);
282 glm::vec3 drawOffsetFor(EntityId entity)
const;
290 bool adoptServerTick(uint32_t serverTick);
295 std::unique_ptr<NetConnection> m_connection;
297 PlayerId m_localPlayer = NO_PLAYER;
298 EntityId m_localEntity;
299 uint64_t m_token = 0;
301 bool m_warnedTickJump =
false;
304 Prediction m_prediction;
306 NetInterpolation m_interpolation;
307 std::vector<uint32_t> m_touched;
bool isPlaying() const
From the Welcome until the session ends.
Definition net_client.h:113
void ageLeases()
Count every lease down a tick, outside a replay, and hand back the lapsed.
void close()
Tell the server goodbye and forget everything this session held.
void endReplay(const Scene &scene)
Finish the replay and measure what the picture owes for it.
void endTick(const Scene &scene, uint32_t tick)
Record where this end's own entity ended tick.
void removeDrawCorrection(Scene &scene)
Take back what applyDrawCorrection applied.
void beginTick(const InputCommand &command)
Keep command until the server says it ran it.
bool simulates(EntityId entity) const
Whether this end decides entity: its own, or one it leases.
void forgetWorld()
Drop everything naming an entity; see NetSession::forgetWorld.
bool receive(Scene &scene, ResourceManager &resources)
Take what has arrived, one datagram at a time, then build what was spawned.
void open(const NetAddress &server)
Start talking to server. Nothing is sent until the first tick has run.
void send()
Send a Hello until welcomed, then the commands the server has not heard.
void applyDrawCorrection(Scene &scene, float deltaTime)
Work a little of every outstanding correction off, and apply the rest.
void lease(const std::vector< EntityId > &entities)
See NetSession::lease.
Open type-erased resource registry with typed handles and generational lifetimes.
Definition resource_manager.h:46
Central registry managing entities and an open set of component types.
Definition scene.h:29
Names one entity of one Scene, for as long as that slot holds it.
Definition entity.h:23
Where a datagram came from, or is going to: an IPv4 host and a port.
Definition net_address.h:13
What a session's server and client halves share: the socket, what the two ends agreed,...
Definition net_session.h:53
What a server built at this root after the scene loaded, so every client can build the same.
Definition net_spawn.h:19