vkmEngine 1.0.0
A C++ game engine · vkmengine.com
Loading...
Searching...
No Matches
net_session.h
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <string>
6#include <vector>
7
8#include "ecs/component/core/transform.h"
9#include "ecs/entity.h"
10#include "net/net_client.h"
11#include "net/net_server.h"
12#include "net/prediction/command.h"
13#include "net/transport/connection.h"
14#include "net/wire/bit_stream.h"
15#include "net/wire/protocol.h"
16#include "platform/net/udp_socket.h"
17
18namespace Vkm::Engine {
19
20class Scene;
21class ResourceManager;
22
29constexpr float NET_SNAPSHOT_RATE = 64.0f;
30
37constexpr float NET_COMMAND_RATE = 64.0f;
38
47constexpr uint32_t NET_MAX_TICK_RATE = static_cast<uint32_t>(2.0f * NET_COMMAND_RATE);
48
53struct NetCore {
60 static constexpr size_t MAX_READS_PER_FRAME = 512;
61
62 UdpSocket socket;
63 uint32_t tickRate = 0;
64
65 uint32_t actionCount = 0;
66
69 uint64_t actionNames = 0;
70 bool ticked = false;
71
72 uint64_t world = 0;
73
76 uint32_t serverTick = 0;
77
78 std::string lastError;
79
80 std::vector<uint8_t> scratch;
81 std::vector<uint8_t> payload;
82 std::vector<uint8_t> datagram;
83 std::vector<uint16_t> acknowledged;
84};
85
94void sendBare(NetCore& core, NetConnection& connection, NetMessage message, uint64_t token);
95
105BitReader receivedPayload(const NetCore& core);
106
116class NetSession {
117 public:
126 class Drawn {
127 public:
135 Drawn(NetSession& session, Scene& scene, float deltaTime);
136 ~Drawn();
137
138 Drawn(const Drawn& other) = delete;
139 Drawn& operator=(const Drawn& other) = delete;
140
141 Drawn(Drawn && other) = delete;
142 Drawn& operator=(Drawn && other) = delete;
143
144 private:
145 NetSession& m_session;
146 Scene& m_scene;
147 };
148
156 class Rewind {
157 public:
170 Rewind(NetSession& session, Scene& scene, EntityId shooter);
171 ~Rewind();
172
173 Rewind(const Rewind& other) = delete;
174 Rewind& operator=(const Rewind& other) = delete;
175
176 Rewind(Rewind && other) = delete;
177 Rewind& operator=(Rewind && other) = delete;
178
179 private:
180 NetSession& m_session;
181 Scene& m_scene;
182 };
183
184 public:
185 NetSession();
186 ~NetSession();
187
188 NetSession(const NetSession& other) = delete;
189 NetSession& operator=(const NetSession& other) = delete;
190
191 NetSession(NetSession && other) = delete;
192 NetSession& operator=(NetSession && other) = delete;
193
194 public:
204 void setWorld(uint64_t fingerprint) { m_core.world = fingerprint; }
205
218 bool host(uint16_t port, uint32_t maxPlayers, uint32_t tickRate);
219
228 bool connect(const NetAddress& server, uint32_t tickRate);
229
231 void close();
232
235
236 public:
237 NetRole role() const { return m_role; }
238 bool isOffline() const { return m_role == NetRole::Offline; }
239
241 bool isDisconnected() const { return m_role == NetRole::Disconnected; }
242
249 bool isPlaying() const;
250
252 const std::string& lastError() const { return m_core.lastError; }
253
254 PlayerId localPlayer() const { return m_client.localPlayer(); }
255
261 NetAddress localAddress() const { return m_core.socket.localAddress(); }
262
268 EntityId localEntity() const { return m_client.localEntity(); }
269
271 float roundTrip() const;
272
282 size_t playerCount() const;
283
284 public:
296 bool simulates(EntityId entity) const;
297
311 void lease(const std::vector<EntityId>& entities) { m_client.lease(entities); }
312
318 size_t leaseCount() const { return m_client.leaseCount(); }
319
327 bool isMine(EntityId entity) const;
328
339 const InputCommand& commandFor(EntityId entity) const;
340
341 public:
351 void receive(Scene& scene, ResourceManager& resources);
352
361 const std::vector<InputCommand>& replayCommands() const { return m_client.replayCommands(); }
362
370 void beginReplayTick(const InputCommand& command);
371
373 void endReplay(Scene& scene) { m_client.endReplay(scene); }
374
380 bool replaying() const { return m_client.replaying(); }
381
391 void endTick(Scene& scene, uint32_t tick);
392
407 uint32_t tick,
408 const InputCommand& command,
409 uint32_t actionCount,
410 uint64_t actionNames = 0
411 );
412
414 void send(Scene& scene, uint32_t tick);
415
434 Scene& scene,
435 ResourceManager& resources,
436 const std::string& prefab,
437 const Transform& at
438 );
439
446 void advance(float seconds);
447
457 void interpolate(Scene& scene, float deltaTime);
458
465 float renderDelay() const;
466
475 float pacing() const;
476
483 float predictionError() const { return m_client.predictionError(); }
484
485 public:
493 std::string describe() const;
494
495 private:
502 bool acceptsTickRate(uint32_t tickRate);
503
509 void disconnect();
510
518 void forgetWorld();
519
520 void beginRewind(Scene& scene, EntityId shooter);
521 void endRewind(Scene& scene);
522
523 private:
524 NetCore m_core;
525 NetServer m_server;
526 NetClient m_client;
527 NetRole m_role = NetRole::Offline;
528
530 InputCommand m_currentCommand;
531
533 float m_sendAccumulator = 1.0f;
534
535 uint32_t m_rewindDepth = 0;
536 EntityId m_rewoundFor;
537
538 uint64_t m_worldEpoch = 0;
539};
540
541} // namespace Vkm::Engine
Reads back what a BitWriter wrote, in the same order.
Definition bit_stream.h:145
A guest's half of a NetSession: joining, predicting what it owns, being corrected,...
Definition net_client.h:42
One end of one conversation: sequencing, acknowledgement and timing.
Definition connection.h:34
The authority's half of a NetSession: seats, the join handshake, commands in and snapshots out.
Definition net_server.h:33
std::function< void(Scene &, ResourceManager &, PlayerId, EntityId)> DespawnPlayer
Undo what SpawnPlayer did.
Definition net_server.h:47
std::function< EntityId(Scene &, ResourceManager &, PlayerId)> SpawnPlayer
What a joining player is given, decided by the game.
Definition net_server.h:40
Drawn(NetSession &session, Scene &scene, float deltaTime)
Works a little of the correction off and applies the rest.
Rewind(NetSession &session, Scene &scene, EntityId shooter)
Rewinds to the moment shooter was drawing when the running command was made.
void setWorld(uint64_t fingerprint)
Say which world this end loaded, so both can agree they match.
Definition net_session.h:204
void receive(Scene &scene, ResourceManager &resources)
Apply everything that has arrived.
bool isMine(EntityId entity) const
Whether entity belongs to the player at this end.
float pacing() const
How much faster than the wall clock this end should run its ticks.
size_t playerCount() const
How many players this end knows of.
bool host(uint16_t port, uint32_t maxPlayers, uint32_t tickRate)
Take players on port.
const std::vector< InputCommand > & replayCommands() const
The ticks a correction wants run again, oldest first.
Definition net_session.h:361
EntityId spawn(Scene &scene, ResourceManager &resources, const std::string &prefab, const Transform &at)
Build prefab at at, here and on every client.
void endTick(Scene &scene, uint32_t tick)
Record what this end predicted for the tick that just ran.
void beginTick(uint32_t tick, const InputCommand &command, uint32_t actionCount, uint64_t actionNames=0)
Take the command this tick runs under.
void interpolate(Scene &scene, float deltaTime)
Draw what this end is only told about where it was a moment ago.
EntityId localEntity() const
The entity this end drives; null on a server.
Definition net_session.h:268
void lease(const std::vector< EntityId > &entities)
Also simulate entities, for a while.
Definition net_session.h:311
void beginReplayTick(const InputCommand &command)
Take command for a tick being run a second time.
void endReplay(Scene &scene)
Finish the replay and clear the request.
Definition net_session.h:373
NetAddress localAddress() const
The address this end is bound to; the real port after hosting on zero.
Definition net_session.h:261
float renderDelay() const
How far behind the server this end is drawing, in ticks; zero when it holds the present.
bool connect(const NetAddress &server, uint32_t tickRate)
Join the game at server.
const std::string & lastError() const
Why the last attempt to join ended, or an empty string.
Definition net_session.h:252
void onSpawn(NetServer::SpawnPlayer spawn, NetServer::DespawnPlayer despawn)
What the game does when a player joins and leaves. Set before host().
size_t leaseCount() const
How many bodies this end is simulating on top of its own.
Definition net_session.h:318
void advance(float seconds)
Wall-clock time passing, for the timers that must run while the simulation does not - a paused editor...
bool isDisconnected() const
True when a session was open and the other end has gone.
Definition net_session.h:241
bool simulates(EntityId entity) const
Whether this end decides what happens to entity.
void send(Scene &scene, uint32_t tick)
Send what this frame produced. Called once a frame, after the ticks.
void close()
Say goodbye and go back to Offline. Safe to call when already offline.
bool replaying() const
True while a tick that already happened is being run again.
Definition net_session.h:380
const InputCommand & commandFor(EntityId entity) const
The input driving entity on the tick about to run.
std::string describe() const
One line describing the session, for a log or a readout.
bool isPlaying() const
True once this end can play: always for a server, and for a client from the Welcome until the connect...
float roundTrip() const
Round trip to the server, in seconds. Zero on a server or offline.
float predictionError() const
How far this end's prediction of its own entity was out, last time the server said.
Definition net_session.h:483
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
A non-blocking UDP socket, the same on Windows and Linux.
Definition udp_socket.h:17
Names one entity of one Scene, for as long as that slot holds it.
Definition entity.h:23
Everything one simulation tick was told to do, as a value.
Definition input_command.h:25
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
uint64_t world
Which world this end loaded, or zero for none.
Definition net_session.h:72
uint32_t tickRate
Fixed for the session.
Definition net_session.h:63
static constexpr size_t MAX_READS_PER_FRAME
Datagrams read in one frame.
Definition net_session.h:60
uint64_t actionNames
Definition net_session.h:69
bool ticked
A tick has run, so the count is real.
Definition net_session.h:70
std::vector< uint8_t > payload
What an outgoing message is written into.
Definition net_session.h:81
std::vector< uint8_t > datagram
The datagram last received, or last framed to send.
Definition net_session.h:82
uint32_t serverTick
Definition net_session.h:76
Local position, rotation and scale of an entity.
Definition transform.h:17