Skip to content

Commit 2ab0065

Browse files
committed
Redesign time sync to track frame advantage per peer
1 parent 7f51e61 commit 2ab0065

6 files changed

Lines changed: 64 additions & 81 deletions

File tree

GekkoLib/include/backend.h

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,30 @@ namespace Gekko {
3131
bool IsValid(Frame current_ack, Frame current_last_input) const;
3232
};
3333

34+
struct AdvantageHistory {
35+
public:
36+
void Init();
37+
38+
void Update(Frame frame);
39+
40+
f32 GetAverageAdvantage();
41+
42+
void SetLocalAdvantage(i8 adv);
43+
44+
void SetRemoteAdvantage(i8 adv);
45+
46+
private:
47+
static const i32 HISTORY_SIZE = 26;
48+
49+
i8 _local_frame_adv;
50+
51+
i8 _remote_frame_adv;
52+
53+
i8 _local[HISTORY_SIZE];
54+
55+
i8 _remote[HISTORY_SIZE];
56+
};
57+
3458
class Player
3559
{
3660
public:
@@ -61,38 +85,14 @@ namespace Gekko {
6185

6286
u64 last_input_send_time = 0;
6387

88+
AdvantageHistory adv_history;
89+
6490
private:
6591
GekkoPlayerType _type;
6692

6793
PlayerStatus _status;
6894
};
6995

70-
struct AdvantageHistory {
71-
public:
72-
void Init();
73-
74-
void Update(Frame frame);
75-
76-
f32 GetAverageAdvantage();
77-
78-
i8 GetLocalAdvantage();
79-
80-
void SetLocalAdvantage(i8 adv);
81-
82-
void SetRemoteAdvantage(i8 adv);
83-
84-
private:
85-
static const i32 HISTORY_SIZE = 32;
86-
87-
i8 _local_frame_adv;
88-
89-
i8 _remote_frame_adv;
90-
91-
i8 _local[HISTORY_SIZE];
92-
93-
i8 _remote[HISTORY_SIZE];
94-
};
95-
9696
class MessageSystem {
9797
public:
9898
MessageSystem();
@@ -107,7 +107,7 @@ namespace Gekko {
107107

108108
void HandleData(GekkoNetAdapter* host, GekkoNetResult** data, u32 length);
109109

110-
void SendInputAck(Handle player, Frame frame);
110+
void SendInputAck(Handle player, Frame frame, i8 local_advantage);
111111

112112
Frame GetLastAddedInput(bool spectator = false);
113113

@@ -128,9 +128,7 @@ namespace Gekko {
128128

129129
std::vector<std::unique_ptr<Player>> spectators;
130130

131-
AdvantageHistory history;
132-
133-
SessionEventSystem session_events;
131+
SessionEventSystem session_events;
134132

135133
std::map<Frame, u32> local_health;
136134

GekkoLib/include/session.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ namespace Gekko {
7575

7676
void HandleSavingConfirmedFrame();
7777

78-
void UpdateLocalFrameAdvantage();
79-
8078
void SendSessionHealthCheck();
8179

8280
void SendNetworkHealthCheck();

GekkoLib/src/backend.cpp

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ Gekko::MessageSystem::MessageSystem()
2525
std::srand((unsigned int)std::time(nullptr));
2626
_session_magic = std::rand();
2727

28-
history = AdvantageHistory();
2928
session_events = SessionEventSystem();
3029
}
3130

@@ -36,7 +35,6 @@ void Gekko::MessageSystem::Init(u8 num_players, u32 input_size)
3635

3736
_net_player_queue.resize(num_players);
3837

39-
history.Init();
4038
}
4139

4240

@@ -198,7 +196,7 @@ void Gekko::MessageSystem::SendSyncResponse(NetAddress* addr, u16 magic)
198196
message->pkt.body = std::move(body);
199197
}
200198

201-
void Gekko::MessageSystem::SendInputAck(Handle player, Frame frame)
199+
void Gekko::MessageSystem::SendInputAck(Handle player, Frame frame, i8 local_advantage)
202200
{
203201
auto plyr = GetPlayerByHandle(player);
204202

@@ -215,7 +213,7 @@ void Gekko::MessageSystem::SendInputAck(Handle player, Frame frame)
215213

216214
auto body = std::make_unique<InputAckMsg>();
217215
body->ack_frame = frame;
218-
body->frame_advantage = history.GetLocalAdvantage();
216+
body->frame_advantage = local_advantage;
219217

220218
message->pkt.body = std::move(body);
221219
}
@@ -619,7 +617,6 @@ void Gekko::MessageSystem::OnInputs(NetAddress& addr, NetPacket& pkt)
619617

620618
const Frame start_frame = body->start_frame;
621619
const u32 input_count = body->input_count;
622-
const Frame end_frame = start_frame + input_count;
623620

624621
const bool is_spectator = (pkt.header.type == SpectatorInputs);
625622

@@ -657,29 +654,19 @@ void Gekko::MessageSystem::OnInputs(NetAddress& addr, NetPacket& pkt)
657654
void Gekko::MessageSystem::OnInputAck(NetAddress& addr, NetPacket& pkt)
658655
{
659656
auto body = (InputAckMsg*)pkt.body.get();
660-
// we should just update the ack frame for all handles where the address matches
661-
const Frame ack_frame = body->ack_frame;
662-
const i32 remote_advantage = body->frame_advantage;
663-
bool added_advantage = false;
657+
const Frame ack_frame = body->ack_frame;
658+
const i8 remote_advantage = (i8)body->frame_advantage;
664659

665-
std::vector<std::unique_ptr<Player>>* current = &remotes;
666-
for (u32 i = 0; i < 2; i++)
667-
{
668-
if (i == 1) {
669-
current = &spectators;
660+
for (auto& player : remotes) {
661+
if (player->address.Equals(addr) && player->stats.last_acked_frame < ack_frame) {
662+
player->stats.last_acked_frame = ack_frame;
663+
player->adv_history.SetRemoteAdvantage(remote_advantage);
670664
}
665+
}
671666

672-
for (auto& player : *current) {
673-
if (player->address.Equals(addr)) {
674-
if (player->stats.last_acked_frame < ack_frame) {
675-
player->stats.last_acked_frame = ack_frame;
676-
// only add remote advantages once
677-
if (!added_advantage && i == 0) {
678-
history.SetRemoteAdvantage(remote_advantage);
679-
added_advantage = true;
680-
}
681-
}
682-
}
667+
for (auto& player : spectators) {
668+
if (player->address.Equals(addr) && player->stats.last_acked_frame < ack_frame) {
669+
player->stats.last_acked_frame = ack_frame;
683670
}
684671
}
685672
}
@@ -923,6 +910,3 @@ void Gekko::AdvantageHistory::SetRemoteAdvantage(i8 adv) {
923910
_remote_frame_adv = adv;
924911
}
925912

926-
i8 Gekko::AdvantageHistory::GetLocalAdvantage() {
927-
return _local_frame_adv;
928-
}

GekkoLib/src/game_session.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,15 @@ f32 Gekko::GameSession::FramesAhead()
168168
return 0.f;
169169
}
170170

171-
return _msg.history.GetAverageAdvantage();
171+
f32 sum = 0.f;
172+
i32 count = 0;
173+
for (auto& remote : _msg.remotes) {
174+
if (remote->GetStatus() == Connected) {
175+
sum += remote->adv_history.GetAverageAdvantage();
176+
count++;
177+
}
178+
}
179+
return count > 0 ? sum / (f32)count : 0.f;
172180
}
173181

174182
void Gekko::GameSession::NetworkStats(i32 player, GekkoNetworkStats* stats)
@@ -236,19 +244,6 @@ void Gekko::GameSession::HandleSavingConfirmedFrame()
236244
assert(_sync.GetCurrentFrame() == current);
237245
}
238246

239-
void Gekko::GameSession::UpdateLocalFrameAdvantage()
240-
{
241-
if (!_started) {
242-
return;
243-
}
244-
245-
const Frame min = _sync.GetMinReceivedFrame();
246-
const Frame current = _sync.GetCurrentFrame();
247-
const i32 local_advantage = current - min;
248-
249-
_msg.history.SetLocalAdvantage(local_advantage);
250-
}
251-
252247
void Gekko::GameSession::SendSessionHealthCheck()
253248
{
254249
if (!_config.desync_detection) {
@@ -406,9 +401,6 @@ void Gekko::GameSession::Poll()
406401
// handle received inputs
407402
HandleReceivedInputs();
408403

409-
// update local frame advantage
410-
UpdateLocalFrameAdvantage();
411-
412404
// add local input for the network
413405
SendLocalInputs();
414406

@@ -454,12 +446,15 @@ void Gekko::GameSession::HandleReceivedInputs()
454446

455447
auto& input_q = _msg.GetNetPlayerQueue(handle);
456448
const Frame min_frame = last_added - (i32)input_q.size() + 1;
449+
const Frame current_frame = _sync.GetCurrentFrame();
450+
const Frame local_delay = (Frame)GetMinLocalDelay();
457451
for (int i = last_recv; i <= last_added; i++) {
458452
if (i >= min_frame) {
459453
int current_idx = i - min_frame;
460454
u8* input = input_q[current_idx].get();
461455
_sync.AddRemoteInput(handle, input, i);
462-
_msg.SendInputAck(handle, i);
456+
const i8 local_adv = (i8)(current_frame - i - local_delay);
457+
_msg.SendInputAck(handle, i, local_adv);
463458
}
464459
}
465460
}
@@ -480,9 +475,16 @@ void Gekko::GameSession::SendLocalInputs()
480475
}
481476
_msg.AddInput(frame, player->handle, input.get());
482477
}
483-
// Record advantage snapshot once per actual game frame
478+
// Record per-peer advantage snapshot once per actual game frame
484479
if (frame == current) {
485-
_msg.history.Update(frame);
480+
const Frame current_frame = _sync.GetCurrentFrame();
481+
for (auto& remote : _msg.remotes) {
482+
if (remote->GetStatus() == Connected) {
483+
const i8 local_adv = (i8)(current_frame - _sync.GetLastReceivedFrom(remote->handle) - (Frame)delay);
484+
remote->adv_history.SetLocalAdvantage(local_adv);
485+
remote->adv_history.Update(frame);
486+
}
487+
}
486488
}
487489
}
488490
}

GekkoLib/src/player.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Gekko::Player::Player(Handle phandle, GekkoPlayerType type, NetAddress* addr, u3
1414

1515
_type = type;
1616
_status = _type == GekkoLocalPlayer ? Connected : Initiating;
17+
adv_history.Init();
1718
}
1819

1920
GekkoPlayerType Gekko::Player::GetType()

GekkoLib/src/spectator_session.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ void Gekko::SpectatorSession::HandleReceivedInputs()
204204
int current_idx = i - min_frame;
205205
u8* input = input_q[current_idx].get();
206206
_sync.AddRemoteInput(handle, input, i);
207-
_msg.SendInputAck(handle, i);
207+
_msg.SendInputAck(handle, i, 0);
208208
}
209209
}
210210
}

0 commit comments

Comments
 (0)