@@ -23,6 +23,7 @@ const double delta = 1.0 / 60.0;
2323class TDSControlledObject : public NS ::LocalSceneObject {
2424public:
2525 NS::ObjectLocalId local_id = NS::ObjectLocalId::NONE;
26+ bool modify_input_on_next_frame = false ;
2627
2728 TDSControlledObject () = default ;
2829
@@ -76,6 +77,12 @@ class TDSControlledObject : public NS::LocalSceneObject {
7677 void controller_process (double p_delta, DataBuffer &p_buffer) {
7778 bool advance_or_turn;
7879 p_buffer.read (advance_or_turn);
80+
81+ if (modify_input_on_next_frame) {
82+ modify_input_on_next_frame = false ;
83+ advance_or_turn = !advance_or_turn;
84+ }
85+
7986 NS::VarData current = get_xy ();
8087 if (advance_or_turn) {
8188 // Advance
@@ -303,6 +310,7 @@ struct TestDollSimulationStorePositions : public TestDollSimulationBase {
303310 ASSERT_COND (NS::LocalSceneSynchronizer::var_data_compare (controlled_2_peer1->get_xy (), NS::VarData (0 , 0 )));
304311 }
305312
313+ // Used to introduce a desync by changing the input on the server.
306314 std::map<NS::FrameIndex, NS::VarData> controlled_1_player_position;
307315 std::map<NS::FrameIndex, NS::VarData> controlled_2_player_position;
308316 std::map<NS::FrameIndex, NS::VarData> controlled_1_doll_position;
@@ -609,13 +617,65 @@ void test_latency() {
609617 ASSERT_COND (test.server_scene .scene_sync ->get_peer_latency (peer2) >= 60 && test.server_scene .scene_sync ->get_peer_latency (peer2) <= 105 );
610618}
611619
620+ void test_simulation_with_wrong_input () {
621+ TestDollSimulationStorePositions test;
622+ test.frame_confirmation_timespan = 1.0 / 10.0 ;
623+ test.init_test ();
624+
625+ const NS::PeerNetworkedController *server_controller_1 = test.server_scene .scene_sync ->get_controller_for_peer (test.peer_1_scene .get_peer ());
626+ const NS::PeerNetworkedController *server_controller_2 = test.server_scene .scene_sync ->get_controller_for_peer (test.peer_2_scene .get_peer ());
627+
628+ test.do_test (30 );
629+
630+ // 1. Make sure no desync were detected so far.
631+ ASSERT_COND (test.peer1_desync_detected .size () == 0 );
632+ ASSERT_COND (test.peer2_desync_detected .size () == 0 );
633+
634+ // Ensure the positions are all the same.
635+ test.assert_positions (NS::FrameIndex{ 0 }, NS::FrameIndex{ 0 });
636+
637+ // 2. Now introduce a desync on the server.
638+ for (int test_count = 0 ; test_count < 4 ; test_count++) {
639+ for (int i = 0 ; i < 3 ; i++) {
640+ const NS::FrameIndex c1_assert_after = server_controller_1->get_current_frame_index () + 15 ;
641+ const NS::FrameIndex c2_assert_after = server_controller_2->get_current_frame_index () + 15 ;
642+ const int c1_desync_vec_size = test.peer1_desync_detected .size ();
643+ const int c2_desync_vec_size = test.peer2_desync_detected .size ();
644+
645+ test.controlled_1_serv ->modify_input_on_next_frame = true ;
646+ test.controlled_2_serv ->modify_input_on_next_frame = true ;
647+ // Process 50 frames and ensure it recovers.
648+ test.do_test (50 );
649+
650+ // Ensure there was a desync.
651+ ASSERT_COND (test.peer1_desync_detected .size () > c1_desync_vec_size);
652+ ASSERT_COND (test.peer2_desync_detected .size () > c2_desync_vec_size);
653+
654+ // But the position should be the same after frame 60 at least
655+ test.assert_no_desync (c1_assert_after, c2_assert_after);
656+ test.assert_positions (c1_assert_after, c2_assert_after);
657+ }
658+
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 ) {
664+ test.network_properties .rtt_seconds = 0.1 ;
665+ } else {
666+ test.network_properties .rtt_seconds = 0.0 ;
667+ }
668+ }
669+ }
670+
612671void test_doll_simulation () {
613672 test_simulation_without_reconciliation (0.0 );
614673 test_simulation_without_reconciliation (1 . / 30 .);
615674 test_simulation_reconciliation (0.0 );
616675 test_simulation_reconciliation (1.0 / 10.0 );
617676 test_simulation_with_latency ();
618677 test_simulation_with_hiccups ();
678+ test_simulation_with_wrong_input ();
619679 // TODO test with great latency and lag compensation.
620680 test_latency ();
621681}
0 commit comments