Skip to content

Commit 2596aaf

Browse files
committed
Fixes the doll not applying server snapshot in some cases.
1 parent e56ce98 commit 2596aaf

2 files changed

Lines changed: 37 additions & 33 deletions

File tree

core/peer_networked_controller.cpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,21 +1488,19 @@ bool DollController::fetch_next_input(double p_delta) {
14881488
void DollController::process(double p_delta) {
14891489
const bool is_new_input = fetch_next_input(p_delta);
14901490

1491-
if (is_new_input) {
1492-
if (queued_instant_to_process >= 0) {
1493-
// The rewinding is in progress.
1494-
// On the doll the rewind's processing takes care to apply the server
1495-
// snapshot if it's found.
1496-
// This operation is done here, because the doll process on a different
1497-
// timeline than the one processed by the client.
1498-
// 1. Try fetching the previous server snapshot.
1499-
auto server_snap_it = VecFunc::find(server_snapshots, DollSnapshot(current_input_buffer_id - 1));
1500-
if (server_snap_it != server_snapshots.end()) {
1501-
// 2. The snapshot was found, so apply it.
1502-
static_cast<ClientSynchronizer *>(peer_controller->scene_synchronizer->get_synchronizer_internal())->apply_snapshot(server_snap_it->data, 0, 0, nullptr, true, true, true, true, true);
1503-
}
1491+
if make_likely (current_input_buffer_id > FrameIndex{ 0 }) {
1492+
// This operation is done here, because the doll process on a different
1493+
// timeline than the one processed by the client.
1494+
// Whenever it found a server snapshot, it's applied.
1495+
// 1. Try fetching the previous server snapshot.
1496+
auto server_snap_it = VecFunc::find(server_snapshots, DollSnapshot(current_input_buffer_id - 1));
1497+
if (server_snap_it != server_snapshots.end()) {
1498+
// 2. The snapshot was found, so apply it.
1499+
static_cast<ClientSynchronizer *>(peer_controller->scene_synchronizer->get_synchronizer_internal())->apply_snapshot(server_snap_it->data, 0, 0, nullptr, true, true, true, true, true);
15041500
}
1501+
}
15051502

1503+
if (is_new_input) {
15061504
SceneSynchronizerDebugger::singleton()->print(INFO, "Doll process index: " + std::string(current_input_buffer_id), "CONTROLLER-" + std::to_string(peer_controller->authority_peer));
15071505

15081506
peer_controller->get_inputs_buffer_mut().begin_read();

tests/test_doll_simulation.cpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -412,17 +412,27 @@ void test_simulation_reconciliation(float p_frame_confirmation_timespan) {
412412
// Run another 30 frames.
413413
test.do_test(30);
414414

415-
// Ensure it was able to reconcily in exactly 1 frame.
416-
ASSERT_COND(test.peer1_desync_detected.size() == 1);
417-
ASSERT_COND(test.peer2_desync_detected.size() == 1);
418-
419-
// Make sure the reconciliation was successful.
420-
// NOTE: 45 is a margin established basing on the `p_frame_confirmation_timespan`.
421-
const NS::FrameIndex ensure_no_desync_after{ 45 };
422-
test.assert_no_desync(ensure_no_desync_after, ensure_no_desync_after);
423-
424-
// and despite that the simulations are correct.
425-
test.assert_positions(ensure_no_desync_after, ensure_no_desync_after);
415+
if (p_frame_confirmation_timespan <= 0.0) {
416+
// Ensure it was able to reconcile right away.
417+
// With `p_frame_confirmation_timespan == 0` the server snapshot is
418+
// received before the doll process it, and since the doll is able to
419+
// apply the server's snapshot during the normal processing, the desync
420+
// is not even triggered.
421+
ASSERT_COND(test.peer1_desync_detected.size() == 0);
422+
ASSERT_COND(test.peer2_desync_detected.size() == 0);
423+
} else {
424+
// Ensure it was able to reconcile in exactly 1 frame.
425+
ASSERT_COND(test.peer1_desync_detected.size() == 1);
426+
ASSERT_COND(test.peer2_desync_detected.size() == 1);
427+
428+
// Make sure the reconciliation was successful.
429+
// NOTE: 45 is a margin established basing on the `p_frame_confirmation_timespan`.
430+
const NS::FrameIndex ensure_no_desync_after{ 45 };
431+
test.assert_no_desync(ensure_no_desync_after, ensure_no_desync_after);
432+
433+
// and despite that the simulations are correct.
434+
test.assert_positions(ensure_no_desync_after, ensure_no_desync_after);
435+
}
426436
}
427437

428438
void test_simulation_with_hiccups(TestDollSimulationStorePositions &test) {
@@ -433,7 +443,7 @@ void test_simulation_with_hiccups(TestDollSimulationStorePositions &test) {
433443
NS::FrameIndex controller_1_doll_frame_index = test.peer_2_scene.scene_sync->get_controller_for_peer(test.peer_1_scene.get_peer())->get_current_frame_index();
434444
NS::FrameIndex controller_2_doll_frame_index = test.peer_1_scene.scene_sync->get_controller_for_peer(test.peer_2_scene.get_peer())->get_current_frame_index();
435445

436-
for (int i = 0; i < 10; i++) {
446+
for (int i = 0; i < 20; i++) {
437447
if (i % 2 == 0) {
438448
test.do_test(10, false, true, false, true);
439449
} else {
@@ -635,10 +645,10 @@ void test_simulation_with_wrong_input() {
635645
test.assert_positions(NS::FrameIndex{ 0 }, NS::FrameIndex{ 0 });
636646

637647
// 2. Now introduce a desync on the server.
638-
for (int test_count = 0; test_count < 5; test_count++) {
648+
for (int test_count = 0; test_count < 20; test_count++) {
639649
for (int i = 0; i < 3; i++) {
640-
const NS::FrameIndex c1_assert_after = server_controller_1->get_current_frame_index() + 20;
641-
const NS::FrameIndex c2_assert_after = server_controller_2->get_current_frame_index() + 20;
650+
const NS::FrameIndex c1_assert_after = server_controller_1->get_current_frame_index() + 40;
651+
const NS::FrameIndex c2_assert_after = server_controller_2->get_current_frame_index() + 40;
642652
const int c1_desync_vec_size = test.peer1_desync_detected.size();
643653
const int c2_desync_vec_size = test.peer2_desync_detected.size();
644654

@@ -656,11 +666,7 @@ void test_simulation_with_wrong_input() {
656666
test.assert_positions(c1_assert_after, c2_assert_after);
657667
}
658668

659-
if (test_count == 1) {
660-
test.network_properties.rtt_seconds = 0.1;
661-
} else if (test_count == 2) {
662-
test.network_properties.rtt_seconds = 0.0;
663-
} else if (test_count == 3) {
669+
if (test_count % 2 == 0) {
664670
test.network_properties.rtt_seconds = 0.1;
665671
} else {
666672
test.network_properties.rtt_seconds = 0.0;

0 commit comments

Comments
 (0)