From 322f0e77f8d7f5b9184484c34a9e22d28f30766f Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Mon, 14 May 2018 00:53:10 +0200 Subject: [PATCH 1/7] Don't generate IRC alerts --- .appveyor.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 63adb70c2..93a9cbae8 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -57,10 +57,3 @@ before_build: build: parallel: true project: build\ALL_BUILD.vcxproj - - -on_success: - - "python %IRC_NOTIFY_SCRIPT% supertuxkart [{author}:{branch}] {short_commit}: {message} {color_green}Succeeded,Details: {build_url},Commit: {commit_url}" - -on_failure: - - "python %IRC_NOTIFY_SCRIPT% supertuxkart [{author}:{branch}] {short_commit}: {message} {color_red}Failed,Details: {build_url},Commit: {commit_url}" From 1fc3e0916e7a9bc450a83df1b86cf23c5a62d8ac Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Tue, 15 May 2018 04:20:44 +0200 Subject: [PATCH 2/7] Ranking related changes --- src/network/network_config.cpp | 1 + src/network/network_config.hpp | 8 ++++++++ src/network/network_player_profile.hpp | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/network/network_config.cpp b/src/network/network_config.cpp index 3579074d5..5949faef1 100644 --- a/src/network/network_config.cpp +++ b/src/network/network_config.cpp @@ -49,6 +49,7 @@ NetworkConfig::NetworkConfig() m_auto_connect = false; m_is_server = false; m_is_public_server = false; + m_is_ranked_server = false; m_done_adding_network_players = false; m_max_players = 4; m_cur_user_id = 0; diff --git a/src/network/network_config.hpp b/src/network/network_config.hpp index 0ad78fe5f..5e9e39fee 100644 --- a/src/network/network_config.hpp +++ b/src/network/network_config.hpp @@ -67,6 +67,9 @@ private: /** True if this host is a server, false otherwise. */ bool m_is_server; + /** True if this is a ranked server */ + bool m_is_ranked_server; + /** The password for a server (or to authenticate to a server). */ std::string m_password; @@ -260,6 +263,11 @@ public: /** Returns if an immediate connection to the first server was * requested. */ bool isAutoConnect() const { return m_auto_connect; } + + // ------------------------------------------------------------------------ + /** Returns if the server use multi-session rankings. */ + bool isRankedServer() const { return m_is_ranked_server; } + // ------------------------------------------------------------------------ /** Returns the minor and majar game mode from server database id. */ std::pair diff --git a/src/network/network_player_profile.hpp b/src/network/network_player_profile.hpp index cbd11f534..3c6970f72 100644 --- a/src/network/network_player_profile.hpp +++ b/src/network/network_player_profile.hpp @@ -65,7 +65,18 @@ private: /** Overall time if grand prix. */ float m_overall_time; + /** Multi-session ranking points */ + int m_ranking_points; + + /** The maximum ranking achieved by this player */ + int m_max_ranking_points; + + /** Number of ranked races */ + unsigned int m_ranked_races; + + public: + NetworkPlayerProfile(std::shared_ptr peer, const irr::core::stringw &name, uint32_t host_id, float default_kart_color, uint32_t online_id, @@ -121,6 +132,18 @@ public: // ------------------------------------------------------------------------ void setOverallTime(float time) { m_overall_time = time; } // ------------------------------------------------------------------------ + int getRankingPoints() const { return m_ranking_points; } + // ------------------------------------------------------------------------ + void setRankingPoints(int points) { m_ranking_points = points; + if (points > m_max_ranking_points) m_max_ranking_points = points; } + // ------------------------------------------------------------------------ + int getMaxRankingPoints() const { return m_max_ranking_points; } + // ------------------------------------------------------------------------ + unsigned int getNumRankedRaces() const { return m_ranked_races; } + // ------------------------------------------------------------------------ + void incrementNumRankedRaces() { m_ranked_races++; } + // ------------------------------------------------------------------------ + void resetGrandPrixData() { m_score = 0; From 9f18c0e2c1836a8b39d2a6c065063c86f2bc4168 Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Tue, 15 May 2018 04:22:23 +0200 Subject: [PATCH 3/7] (Broken) ranking computation --- src/network/protocols/server_lobby.cpp | 134 +++++++++++++++++++++++++ src/network/protocols/server_lobby.hpp | 7 ++ 2 files changed, 141 insertions(+) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index cf09793de..2fd57d272 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -751,6 +751,9 @@ void ServerLobby::checkRaceFinished() total->addUInt32(last_score).addUInt32(cur_score) .addFloat(overall_time); } + + if (NetworkConfig::get()->isRankedServer()) + computeNewRankings(); } else if (race_manager->modeHasLaps()) { @@ -770,6 +773,137 @@ void ServerLobby::checkRaceFinished() } // checkRaceFinished +//----------------------------------------------------------------------------- +/** Compute the new player's rankings in ranked servers + */ +void ServerLobby::computeNewRankings() +{ + //TODO : this is overall a rather naive implementation + // several possibilities to speed up the computation exist, + // though this is minor in importance as it's not done + // during racing. + + //TODO : make some numerical parts of the formulas + // depend of a single constant value + + // No ranking yet for battle mode + // TODO : separate rankings for time-trial and normal and FTL ?? + if (!race_manager->modeHasLaps()) + return; + + auto& players = m_game_setup->getPlayers(); + + std::vector ranking_change; + + for (unsigned i = 0; i < players.size(); i++) + { + ranking_change.push_back(0); + + //FIXME : if the players have been kicked out, there is no way to retrieve the data ! + + //FIXME : can't use a weak_ptr like that + int player1_ranking = players[i]->getRankingPoints(); + float player1_time = race_manager->getKartRaceTime(i); + float player1_factor = computeRankingFactor(i); + + for (unsigned j = 0; j < players.size(); i++) + { + // Don't compare a player with itself + if (i == j) + continue; + + double result = 0.0f; + double expected_result = 0.0f; + double ranking_importance = 0.0f; + + // No change between two quitting players + if (!players[i].lock() && !players[j].lock()) + continue; + + int player2_ranking = players[i]->getRankingPoints(); + float player2_time = race_manager->getKartRaceTime(j); + + // Compute the expected result + double diff = (double) player2_ranking - player1_ranking; + expected_result = 1.0f/(1.0f+std::pow(10.0f, diff/(BASE_RANKING_POINTS/2.0f))); + + // Compute the result and race ranking importance + float player_factors = std::max(player1_factor, + computeRankingFactor(j) ); + + if (!players[i].lock()) + { + result = 0.0f; + ranking_importance = (MAX_SCALING_TIME/20.0f)*player_factors; + } + else if (!players[j].lock()) + { + result = 1.0f; + ranking_importance = (MAX_SCALING_TIME/20.0f)*player_factors; + } + else + { + // If time difference > 2,5% ; the result is 1 or 0 + // Otherwise, it is averaged between 0 and 1. + if (player1_time <= player2_time) + { + result = (player2_time - player1_time)/(player1_time/20); + result = std::min( (double) 1.0f, 0.5f + result); + } + else + { + result = (player1_time - player2_time)/(player2_time/20); + result = std::max( (double) 0.0f, 0.5f - result); + } + ranking_importance = std::min ( std::max (player1_time, player2_time), + MAX_SCALING_TIME ) * player_factors/20.0f; + } + // Compute the ranking change + ranking_change[i] += ranking_importance * (result - expected_result); + } + } + + // Don't merge it in the main loop as long as getRankingPoints + // is called in it + for (unsigned i = 0; i < players.size(); i++) + { + // Add or substract 0.5f so that the cast to int acts like rounding + ranking_change[i] += (ranking_change[i] > 0 ) ? 0.5f : -0.5f; + int old_ranking_points = players[i]->getRankingPoints(); + players[i]->setRankingPoints(old_ranking_points + ((int) ranking_change[i])); + } +} //computeNewRankings + +//----------------------------------------------------------------------------- +/** Compute the ranking factor, used to make top rankings more stable + * and to allow new players to faster get to an appropriate ranking + */ +float ServerLobby::computeRankingFactor(unsigned int player_id) +{ + auto& players = m_game_setup->getPlayers(); + + assert(player_id < players.size()); + + int max_points = players[player_id].getMaxRankingPoints(); + int num_races = players[player_id].getNumRankedRaces(); + + if (max_points >= (int) (BASE_RANKING_POINTS * 2.0f)) + return 1.0f; + else if (max_points >= (int) (BASE_RANKING_POINTS * 1.75f) || num_races > 500) + return 1.25f; + else if (max_points >= (int) (BASE_RANKING_POINTS * 1.5f) || num_races > 250) + return 1.5f; + else if (max_points >= (int) (BASE_RANKING_POINTS * 1.25f) || num_races > 100) + return 1.75f; + // The base ranking points are not distributed all at once + // So it's not guaranteed a player reach them + else if (max_points >= (int) (BASE_RANKING_POINTS ) || num_races > 50) + return 2.0f; + else + return 2.5f; + +} //computeRankingFactor + //----------------------------------------------------------------------------- /** Stop any race currently in server, should only be called in main thread. */ diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 86c76f8da..253875b7c 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -78,6 +78,11 @@ private: TransportAddress m_server_address; + /* Ranking related variables */ + + const float BASE_RANKING_POINTS = 4000.0f; + const float MAX_SCALING_TIME = 600.0f; + // connection management void clientDisconnected(Event* event); void connectionRequested(Event* event); @@ -126,6 +131,8 @@ private: } std::tuple handleVote(); void stopCurrentRace(); + void computeNewRankings(); + float computeRankingFactor(unsigned int player_id); public: ServerLobby(); From b026b24e4a01e712f71bea13f9adf368a0b67e49 Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Tue, 15 May 2018 18:47:59 +0200 Subject: [PATCH 4/7] Fix/update ranking computation --- src/network/protocols/server_lobby.cpp | 102 +++++++++++++++---------- src/network/protocols/server_lobby.hpp | 10 ++- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 2fd57d272..513e58cf0 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -775,34 +775,43 @@ void ServerLobby::checkRaceFinished() //----------------------------------------------------------------------------- /** Compute the new player's rankings in ranked servers + * //FIXME : this function assumes that m_rankings, + * m_num_ranked_races and m_max_ranking + * are correctly filled before + * It also assumes that the data stored by them + * is written back to the main list after the GP */ void ServerLobby::computeNewRankings() { - //TODO : this is overall a rather naive implementation - // several possibilities to speed up the computation exist, - // though this is minor in importance as it's not done - // during racing. + auto players = m_game_setup->getConnectedPlayers(true/*same_index_for_disconnected*/); - //TODO : make some numerical parts of the formulas - // depend of a single constant value + assert (m_rankings.size() == players.size() && + m_num_ranked_races.size() == players.size() && + m_max_ranking.size() == players.size() ); // No ranking yet for battle mode // TODO : separate rankings for time-trial and normal and FTL ?? if (!race_manager->modeHasLaps()) return; - auto& players = m_game_setup->getPlayers(); - + // Using a vector of vector, it would be possible to fill + // all j < i v[i][j] with -v[j][i] + // Would this be worth it ? std::vector ranking_change; + for (unsigned i = 0; i < players.size(); i++) + { + m_rankings[i] += distributeBasePoints(i); + } + for (unsigned i = 0; i < players.size(); i++) { ranking_change.push_back(0); - //FIXME : if the players have been kicked out, there is no way to retrieve the data ! + int player1_ranking = m_rankings[i]; - //FIXME : can't use a weak_ptr like that - int player1_ranking = players[i]->getRankingPoints(); + // If the player has quitted before the race end, + // the value will be incorrect, but it will not be used float player1_time = race_manager->getKartRaceTime(i); float player1_factor = computeRankingFactor(i); @@ -817,13 +826,13 @@ void ServerLobby::computeNewRankings() double ranking_importance = 0.0f; // No change between two quitting players - if (!players[i].lock() && !players[j].lock()) + if (!players[i] && !players[j]) continue; - int player2_ranking = players[i]->getRankingPoints(); + int player2_ranking = m_rankings[j]; float player2_time = race_manager->getKartRaceTime(j); - // Compute the expected result + // Compute the expected result using an ELO-like function double diff = (double) player2_ranking - player1_ranking; expected_result = 1.0f/(1.0f+std::pow(10.0f, diff/(BASE_RANKING_POINTS/2.0f))); @@ -831,15 +840,17 @@ void ServerLobby::computeNewRankings() float player_factors = std::max(player1_factor, computeRankingFactor(j) ); - if (!players[i].lock()) + if (!players[i]) { result = 0.0f; - ranking_importance = (MAX_SCALING_TIME/20.0f)*player_factors; + ranking_importance = + MAX_SCALING_TIME*MAX_POINTS_PER_SECOND*player_factors; } - else if (!players[j].lock()) + else if (!players[j]) { result = 1.0f; - ranking_importance = (MAX_SCALING_TIME/20.0f)*player_factors; + ranking_importance = + MAX_SCALING_TIME*MAX_POINTS_PER_SECOND*player_factors; } else { @@ -856,21 +867,22 @@ void ServerLobby::computeNewRankings() result = std::max( (double) 0.0f, 0.5f - result); } ranking_importance = std::min ( std::max (player1_time, player2_time), - MAX_SCALING_TIME ) * player_factors/20.0f; + MAX_SCALING_TIME ) * MAX_POINTS_PER_SECOND * player_factors; } // Compute the ranking change ranking_change[i] += ranking_importance * (result - expected_result); } } - // Don't merge it in the main loop as long as getRankingPoints - // is called in it + // Don't merge it in the main loop as m_rankings value are used there for (unsigned i = 0; i < players.size(); i++) { - // Add or substract 0.5f so that the cast to int acts like rounding - ranking_change[i] += (ranking_change[i] > 0 ) ? 0.5f : -0.5f; - int old_ranking_points = players[i]->getRankingPoints(); - players[i]->setRankingPoints(old_ranking_points + ((int) ranking_change[i])); + m_rankings[i] += ranking_change[i]; + // This isn't entirely correct when rankings are negatives, but + // the max will always be positive + if ((int) (m_rankings[i]+0.5f) > m_max_ranking[i]) + m_max_ranking[i] = (int) (m_rankings[i]+0.5f); + m_num_ranked_races[i]++; } } //computeNewRankings @@ -880,30 +892,42 @@ void ServerLobby::computeNewRankings() */ float ServerLobby::computeRankingFactor(unsigned int player_id) { - auto& players = m_game_setup->getPlayers(); + int max_points = m_max_ranking[player_id]; + int num_races = m_num_ranked_races[player_id]; - assert(player_id < players.size()); - - int max_points = players[player_id].getMaxRankingPoints(); - int num_races = players[player_id].getNumRankedRaces(); - - if (max_points >= (int) (BASE_RANKING_POINTS * 2.0f)) - return 1.0f; + if ( max_points >= (int) (BASE_RANKING_POINTS * 2.0f)) + return 0.4f; else if (max_points >= (int) (BASE_RANKING_POINTS * 1.75f) || num_races > 500) - return 1.25f; + return 0.5f; else if (max_points >= (int) (BASE_RANKING_POINTS * 1.5f) || num_races > 250) - return 1.5f; + return 0.6f; else if (max_points >= (int) (BASE_RANKING_POINTS * 1.25f) || num_races > 100) - return 1.75f; + return 0.7f; // The base ranking points are not distributed all at once // So it's not guaranteed a player reach them - else if (max_points >= (int) (BASE_RANKING_POINTS ) || num_races > 50) - return 2.0f; + else if (max_points >= (int) (BASE_RANKING_POINTS ) || num_races > 50) + return 0.8f; else - return 2.5f; + return 1.0f; } //computeRankingFactor +//----------------------------------------------------------------------------- +/** Manages the distribution of the base points. + * Gives half of the points immediately and the other half progressively + * by smaller and smaller chuncks from race 1 to 46. + */ +float ServerLobby::distributeBasePoints(unsigned int player_id) +{ + int num_races = m_num_ranked_races[player_id]; + if (num_races == 0) + return BASE_RANKING_POINTS/2.0f; + else if (num_races <= 45) + return (BASE_RANKING_POINTS/2000.0f * std::max((45-num_races),4)*2.0f); + else + return 0.0f; +} + //----------------------------------------------------------------------------- /** Stop any race currently in server, should only be called in main thread. */ diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 253875b7c..eb826c7f9 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -80,8 +80,13 @@ private: /* Ranking related variables */ - const float BASE_RANKING_POINTS = 4000.0f; - const float MAX_SCALING_TIME = 600.0f; + const float BASE_RANKING_POINTS = 4000.0f; + const float MAX_SCALING_TIME = 600.0f; + const float MAX_POINTS_PER_SECOND = 0.125f; + + std::vector m_rankings; // TODO : convert from and to int when communicating with the server. Think to round it correctly + std::vector m_num_ranked_races; + std::vector m_max_ranking; // connection management void clientDisconnected(Event* event); @@ -133,6 +138,7 @@ private: void stopCurrentRace(); void computeNewRankings(); float computeRankingFactor(unsigned int player_id); + float distributeBasePoints(unsigned int player_id); public: ServerLobby(); From 9902e7c7675ab9c02f27d5b2ebfa3dcfa8222a8b Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Thu, 17 May 2018 03:16:12 +0200 Subject: [PATCH 5/7] Use double for max_ranking too, remove first half base-points distribution (done elsewhere) --- src/network/protocols/server_lobby.cpp | 29 +++++++++++++------------- src/network/protocols/server_lobby.hpp | 3 ++- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 513e58cf0..5c8cd871f 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -878,10 +878,9 @@ void ServerLobby::computeNewRankings() for (unsigned i = 0; i < players.size(); i++) { m_rankings[i] += ranking_change[i]; - // This isn't entirely correct when rankings are negatives, but - // the max will always be positive - if ((int) (m_rankings[i]+0.5f) > m_max_ranking[i]) - m_max_ranking[i] = (int) (m_rankings[i]+0.5f); + + if (m_rankings[i] > m_max_ranking[i]) + m_max_ranking[i] = m_rankings[i]; m_num_ranked_races[i]++; } } //computeNewRankings @@ -892,20 +891,20 @@ void ServerLobby::computeNewRankings() */ float ServerLobby::computeRankingFactor(unsigned int player_id) { - int max_points = m_max_ranking[player_id]; + double max_points = m_max_ranking[player_id]; int num_races = m_num_ranked_races[player_id]; - if ( max_points >= (int) (BASE_RANKING_POINTS * 2.0f)) + if ( max_points >= (BASE_RANKING_POINTS * 2.0f)) return 0.4f; - else if (max_points >= (int) (BASE_RANKING_POINTS * 1.75f) || num_races > 500) + else if (max_points >= (BASE_RANKING_POINTS * 1.75f) || num_races > 500) return 0.5f; - else if (max_points >= (int) (BASE_RANKING_POINTS * 1.5f) || num_races > 250) + else if (max_points >= (BASE_RANKING_POINTS * 1.5f) || num_races > 250) return 0.6f; - else if (max_points >= (int) (BASE_RANKING_POINTS * 1.25f) || num_races > 100) + else if (max_points >= (BASE_RANKING_POINTS * 1.25f) || num_races > 100) return 0.7f; // The base ranking points are not distributed all at once // So it's not guaranteed a player reach them - else if (max_points >= (int) (BASE_RANKING_POINTS ) || num_races > 50) + else if (max_points >= (BASE_RANKING_POINTS ) || num_races > 50) return 0.8f; else return 1.0f; @@ -914,15 +913,15 @@ float ServerLobby::computeRankingFactor(unsigned int player_id) //----------------------------------------------------------------------------- /** Manages the distribution of the base points. - * Gives half of the points immediately and the other half progressively - * by smaller and smaller chuncks from race 1 to 46. + * Gives half of the points progressively + * by smaller and smaller chuncks from race 1 to 45. + * The first half is distributed when the player enters + * for the first time in the ranked server. */ float ServerLobby::distributeBasePoints(unsigned int player_id) { int num_races = m_num_ranked_races[player_id]; - if (num_races == 0) - return BASE_RANKING_POINTS/2.0f; - else if (num_races <= 45) + if (num_races < 45) return (BASE_RANKING_POINTS/2000.0f * std::max((45-num_races),4)*2.0f); else return 0.0f; diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index eb826c7f9..e7c7a6833 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -80,13 +80,14 @@ private: /* Ranking related variables */ + // If updating the base points, update the base points distribution in DB const float BASE_RANKING_POINTS = 4000.0f; const float MAX_SCALING_TIME = 600.0f; const float MAX_POINTS_PER_SECOND = 0.125f; std::vector m_rankings; // TODO : convert from and to int when communicating with the server. Think to round it correctly std::vector m_num_ranked_races; - std::vector m_max_ranking; + std::vector m_max_ranking; // connection management void clientDisconnected(Event* event); From 6d6520ab893ddcec9aa9f2867a2cc68f3ed41d1e Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Thu, 17 May 2018 17:37:16 +0200 Subject: [PATCH 6/7] Make the formula different between normal and time-trial modes --- src/network/protocols/server_lobby.cpp | 43 +++++++++++++++++++++++--- src/network/protocols/server_lobby.hpp | 2 ++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 5c8cd871f..368775c1f 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -790,7 +790,7 @@ void ServerLobby::computeNewRankings() m_max_ranking.size() == players.size() ); // No ranking yet for battle mode - // TODO : separate rankings for time-trial and normal and FTL ?? + // TODO : separate rankings for time-trial and normal ?? if (!race_manager->modeHasLaps()) return; @@ -834,23 +834,25 @@ void ServerLobby::computeNewRankings() // Compute the expected result using an ELO-like function double diff = (double) player2_ranking - player1_ranking; - expected_result = 1.0f/(1.0f+std::pow(10.0f, diff/(BASE_RANKING_POINTS/2.0f))); + expected_result = 1.0f/(1.0f+std::pow(10.0f, diff/(BASE_RANKING_POINTS*getModeSpread()/(2.0f)))); // Compute the result and race ranking importance float player_factors = std::max(player1_factor, computeRankingFactor(j) ); + + float mode_factor = getModeFactor(); if (!players[i]) { result = 0.0f; ranking_importance = - MAX_SCALING_TIME*MAX_POINTS_PER_SECOND*player_factors; + mode_factor*MAX_SCALING_TIME*MAX_POINTS_PER_SECOND*player_factors; } else if (!players[j]) { result = 1.0f; ranking_importance = - MAX_SCALING_TIME*MAX_POINTS_PER_SECOND*player_factors; + mode_factor*MAX_SCALING_TIME*MAX_POINTS_PER_SECOND*player_factors; } else { @@ -866,7 +868,7 @@ void ServerLobby::computeNewRankings() result = (player1_time - player2_time)/(player2_time/20); result = std::max( (double) 0.0f, 0.5f - result); } - ranking_importance = std::min ( std::max (player1_time, player2_time), + ranking_importance = mode_factor * std::min ( std::max (player1_time, player2_time), MAX_SCALING_TIME ) * MAX_POINTS_PER_SECOND * player_factors; } // Compute the ranking change @@ -911,6 +913,36 @@ float ServerLobby::computeRankingFactor(unsigned int player_id) } //computeRankingFactor +//----------------------------------------------------------------------------- +/** Returns the mode race importance factor, + * used to make ranking move slower in more random modes. + */ +float ServerLobby::getModeFactor() +{ + if (race_manager->isTimeTrialMode()) + return 1.0f; + + //else + return 0.4f; +} + +//----------------------------------------------------------------------------- +/** Returns the mode factor, used to make ranking move slower in more random + * modes. + */ +float ServerLobby::getModeSpread() +{ + if (race_manager->isTimeTrialMode()) + return 1.0f; + + //else + //TODO : the value used here for normal races is a wild guess. + // When hard data to the spread tendencies of time-trial + // and normal mode becomes available, update this to make + // the spreads more comparable + return 1.4f; +} + //----------------------------------------------------------------------------- /** Manages the distribution of the base points. * Gives half of the points progressively @@ -1553,3 +1585,4 @@ bool ServerLobby::waitingForPlayers() const return m_state.load() == ACCEPTING_CLIENTS && !m_game_setup->isGrandPrixStarted(); } // waitingForPlayers + diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index e7c7a6833..56d5f10b7 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -140,6 +140,8 @@ private: void computeNewRankings(); float computeRankingFactor(unsigned int player_id); float distributeBasePoints(unsigned int player_id); + float getModeFactor(); + float getModeSpread(); public: ServerLobby(); From bac516aa40a718a460e83889a1030b9d5148f115 Mon Sep 17 00:00:00 2001 From: Alayan-stk-2 Date: Thu, 17 May 2018 17:45:49 +0200 Subject: [PATCH 7/7] Update comment --- src/network/protocols/server_lobby.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 368775c1f..ca7b3cd0f 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -927,8 +927,8 @@ float ServerLobby::getModeFactor() } //----------------------------------------------------------------------------- -/** Returns the mode factor, used to make ranking move slower in more random - * modes. +/** Returns the mode spread factor, used so that a similar difference in + * skill will result in a similar ranking difference in more random modes. */ float ServerLobby::getModeSpread() {