The aim of this patch is to reduce the time difference between players. Additionally it should make it possible to remove the switch team notification.
The patch increase the network traffic, however it's not the bad as it looks at the first glance: Previously at least every 100ms an action was sent. An action gets currently encoded with 12 bytes. With the about 40 bytes TCP/IP overhead it are 520 bytes per second which get transferred. It's possible to encode the new GAME_CALCULATE_FRAME action as one byte. Thus if there are 100 physics frames per second only 100 bytes need to be transferred per second. Additionally there is of course TCP/IP overhead, but smart TCP/IP layers will send multiple actions as one TCP/IP package. If the TCP/IP layer chooses to send 10 packages per second then 500 bytes need to be transferred per second if there is an 40 bytes TCP/IP overhead. If the TCP/IP layer chooses to send 100 packages per second then 4100 bytes need to be transferred per second. To be independent of the TCP/IP layer the game can offer the user the service to buffer actions in order to send them in few large packages: This would then decrease the network traffic as the cost of a greater time difference between the two players. --- lib/wormux/include/WORMUX_action.h | 2 +- src/game/game.cpp | 12 +++--------- src/game/game.h | 3 --- src/include/action_handler.cpp | 28 ++++++++++++++-------------- src/network/network.cpp | 13 ------------- src/network/network.h | 2 -- 6 files changed, 18 insertions(+), 42 deletions(-) diff --git a/lib/wormux/include/WORMUX_action.h b/lib/wormux/include/WORMUX_action.h index b6d1190..32c8b9c 100644 --- a/lib/wormux/include/WORMUX_action.h +++ b/lib/wormux/include/WORMUX_action.h @@ -48,6 +48,7 @@ public: ACTION_PLAYER_CHANGE_WEAPON, ACTION_PLAYER_CHANGE_CHARACTER, ACTION_GAMELOOP_NEXT_TEAM, + ACTION_GAME_CALCULATE_FRAME, // ######################################################## // To be sure that rules will be the same on each computer @@ -106,7 +107,6 @@ public: ACTION_NETWORK_RANDOM_INIT, ACTION_INFO_CLIENT_CONNECT, ACTION_INFO_CLIENT_DISCONNECT, - ACTION_ECHO, // ######################################################## } Action_t; diff --git a/src/game/game.cpp b/src/game/game.cpp index c22f74e..16c5ebf 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -223,7 +223,6 @@ Game::Game(): delay(0), time_of_next_frame(0), time_of_next_phy_frame(0), - tick_count_of_next_ping(0), character_already_chosen(false), m_current_turn(0) { } @@ -249,7 +248,6 @@ void Game::Init() FOR_ALL_CHARACTERS(team, character) (*character).ResetDamageStats(); - tick_count_of_next_ping = 0; // 0 = as early as possible SetState(END_TURN, true); // begin with a small pause } @@ -520,12 +518,6 @@ void Game::MainLoop() if (Time::GetInstance()->Read() % 1000 == 20 && Network::GetInstance()->IsGameMaster()) PingClient(); - uint current_tick_count = SDL_GetTicks(); - if (current_tick_count >= tick_count_of_next_ping && Network::GetInstance()->IsTurnMaster()) { - tick_count_of_next_ping = current_tick_count + MS_BETWEEN_PINGS; - Action a(Action::ACTION_NETWORK_PING); - Network::GetInstance()->SendActionToAll(a); - } StatStart("Game:RefreshInput()"); RefreshInput(); StatStop("Game:RefreshInput()"); @@ -536,6 +528,9 @@ void Game::MainLoop() // Refresh the map GetWorld().Refresh(); + Action a(Action::ACTION_GAME_CALCULATE_FRAME); + Network::GetInstance()->SendActionToAll(a); + // try to adjust to max Frame by seconds #ifndef USE_VALGRIND if (time_of_next_frame < Time::GetInstance()->ReadRealTime()) { @@ -553,7 +548,6 @@ void Game::MainLoop() } } #endif - Network::GetInstance()->SendEcho(); delay = time_of_next_phy_frame - Time::GetInstance()->ReadRealTime(); if (delay >= 0) diff --git a/src/game/game.h b/src/game/game.h index 3c0ccba..8ceb2e3 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -77,9 +77,6 @@ private: uint time_of_next_frame; // Time to compute the next physic engine frame uint time_of_next_phy_frame; - uint tick_count_of_next_ping; - // Real time milliseconds intervall in which the turn master pings the other players. - static const uint MS_BETWEEN_PINGS = 100; bool character_already_chosen; diff --git a/src/include/action_handler.cpp b/src/include/action_handler.cpp index 588ab98..3be723f 100644 --- a/src/include/action_handler.cpp +++ b/src/include/action_handler.cpp @@ -324,6 +324,13 @@ static void Action_Game_NextTeam (Action *a) Network::GetInstance()->SetTurnMaster(false); } +static void Action_Game_CalculateFrame (Action */*a*/) +{ + // Nothing to do here: + // The action handler will use the timestamp to set the maximal time. + // The increased time will then trigger the calculation of the next frame. +} + static void Action_DropBonusBox (Action */*a*/) { ObjBox* current_box = Game::GetInstance()->GetCurrentBox(); @@ -755,20 +762,15 @@ static void Action_Weapon_Supertux (Action *a) // ######################################################## -static void Action_Network_RandomInit (Action *a) -{ - MSG_DEBUG("random", "Initialization from network"); - RandomSync().SetRand(a->PopInt()); -} - -// Nothing to do here. Just for time synchronisation -static void Action_Network_Ping(Action */*a*/) +static void Action_Network_Ping (Action */*a*/) { + // Nothing to do here } -// Nothing to do here. The action handler will use the timestamp to set the maximal time. -static void Action_Echo(Action */*a*/) +static void Action_Network_RandomInit (Action *a) { + MSG_DEBUG("random", "Initialization from network"); + RandomSync().SetRand(a->PopInt()); } // ######################################################## @@ -950,6 +952,7 @@ void Action_Handler_Init() ActionHandler::GetInstance()->Register (Action::ACTION_PLAYER_CHANGE_WEAPON, "PLAYER_change_weapon", &Action_Player_ChangeWeapon); ActionHandler::GetInstance()->Register (Action::ACTION_PLAYER_CHANGE_CHARACTER, "PLAYER_change_character", &Action_Player_ChangeCharacter); ActionHandler::GetInstance()->Register (Action::ACTION_GAMELOOP_NEXT_TEAM, "GAMELOOP_change_team", &Action_Game_NextTeam); + ActionHandler::GetInstance()->Register (Action::ACTION_GAME_CALCULATE_FRAME, "GAME_calculate_frame", &Action_Game_CalculateFrame); // ######################################################## // To be sure that rules will be the same on each computer @@ -1007,7 +1010,6 @@ void Action_Handler_Init() ActionHandler::GetInstance()->Register (Action::ACTION_NETWORK_RANDOM_INIT, "NETWORK_random_init", &Action_Network_RandomInit); ActionHandler::GetInstance()->Register (Action::ACTION_INFO_CLIENT_DISCONNECT, "INFO_client_disconnect", &Action_Info_ClientDisconnect); ActionHandler::GetInstance()->Register (Action::ACTION_INFO_CLIENT_CONNECT, "INFO_client_connect", &Action_Info_ClientConnect); - ActionHandler::GetInstance()->Register (Action::ACTION_ECHO, "ACTION_echo", &Action_Echo); // ######################################################## ActionHandler::GetInstance()->UnLock(); } @@ -1042,9 +1044,7 @@ void ActionHandler::ExecActions() { Lock(); a = (*it); - // The action echo gets send at the end of a physics frame: - // No more physic related actions are expected for the current frame. - if (a->GetType() == Action::ACTION_ECHO) + if (a->GetType() == Action::ACTION_GAME_CALCULATE_FRAME) time->RefreshMaxTimePlusOne(a->GetTimestamp() + 1); else time->RefreshMaxTimePlusOne(a->GetTimestamp()); diff --git a/src/network/network.cpp b/src/network/network.cpp index cc28ea2..1e44fc8 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -373,8 +373,6 @@ void Network::SendAction(const Action& a, DistantComputer* client, bool clt_as_r char* packet; int size; - echo_outstanding = true; - a.WriteToPacket(packet, size); ASSERT(packet != NULL); @@ -406,17 +404,6 @@ void Network::SendAction(const Action& a, DistantComputer* client, bool clt_as_r free(packet); } -void Network::SendEcho() { - if (echo_outstanding) - { - Action a(Action::ACTION_ECHO); - SendActionToAll(a); - - // this must be set after SendActionToAll as SendActionToAll would set it to true otherwise. - echo_outstanding = false; - } -} - //----------------------------------------------------------------------------- // Static method diff --git a/src/network/network.h b/src/network/network.h index 61744f8..dbf6618 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -85,7 +85,6 @@ private: Player player; bool turn_master_player; - bool echo_outstanding; protected: bool game_master_player; WNet::net_game_state_t state; @@ -152,7 +151,6 @@ public: void SendActionToAll(const Action& action); void SendActionToOne(const Action& action, DistantComputer* client); void SendActionToAllExceptOne(const Action& action, DistantComputer* client); - void SendEcho(); // Manage network state void SetState(WNet::net_game_state_t state); -- 1.6.0.4 _______________________________________________ Wormux-dev mailing list Wormux-dev@gna.org https://mail.gna.org/listinfo/wormux-dev