Skip to content

Matchmaker games adjust real rating of global while breaking rules of trueskill, causing rating inflation in global #1101

Description

@lL1l1

There's a popular perspective that global rating has inflated in the past few years. What used to be the near-top players at 2k rating is now 2.4k and higher, with some reaching around 2.7k in mostly legitimate gameplay.

I hypothesized that the matchmaker -> global rating adjustment could be the source of that influx of rating for global.

From my limited understand of the code, here's what I understood looking at it:
The game rating adjuster breaks trueskill in 2 ways:

  • It does not reduce the global rating of the opponent if they lose
  • It only allows rating to move up

def compute_rating(
self,
ratings: RatingDict
) -> RatingDict:
"""
Adjust one rating to bring it closer to a different base rating. For
each player, this will rate the game with trueskill as if they
played this game with the rating we are adjusting instead of the
base rating. Adjustments are only returned under certain conditions to
prevent rating manipulation.
"""
new_adjusted_ratings = {}
for player_id, base_rating in self.base_ratings.items():
old_adjusted_rating = ratings[player_id]
# Since we only adjust upwards, we should not adjust ratings that
# are already higher than the base.
if base_rating.displayed() < old_adjusted_rating.displayed():
continue
# Make a copy of the base ratings, but substitute this player's
# rating with the rating we are adjusting.
old_ratings = dict(self.base_ratings)
old_ratings[player_id] = old_adjusted_rating
new_ratings = self.rater.compute_rating(old_ratings)
new_adjusted_rating = new_ratings[player_id]
self._logger.debug(
"Got new adjusted rating for player %d: %s",
player_id,
new_adjusted_rating
)
if (
old_adjusted_rating.displayed() <
new_adjusted_rating.displayed() <=
config.RATING_ADJUSTMENT_MAX_RATING
):
new_adjusted_ratings[player_id] = new_adjusted_rating
return new_adjusted_ratings

As I understand in this function, the rating adjuster adjusts the real global rating history of the player.

async with self._db.acquire() as conn:
# Fetch all players rating info from the database
player_ratings = await self._get_all_player_ratings(
conn, rater.player_ids
)
rating_result = await self._rate_for_leaderboard(
conn,
summary.game_id,
summary.rating_type,
player_ratings,
rater
)
assert rating_result is not None
rating_results.append(rating_result)
# TODO: If we add hidden ratings, make sure to check for them here.
# Hidden ratings should not affect global.
# TODO: Use game_type == "matchmaker" instead?
if summary.rating_type != RatingType.GLOBAL:
self._logger.debug(
"Performing global rating adjustment for players: %s",
rater.player_ids
)
adjustment_rater = AdjustmentGameRater(
rater,
rating_result.old_ratings
)
global_rating_result = await self._rate_for_leaderboard(
conn,
summary.game_id,
RatingType.GLOBAL,
player_ratings,
adjustment_rater,
update_game_player_stats=False
)
if global_rating_result:
rating_results.append(global_rating_result)
for rating_result in rating_results:
await self._publish_rating_changes(
rating_result.game_id,
rating_result.rating_type,
rating_result.old_ratings,
rating_result.new_ratings,
rating_result.outcome_map
)

For a trueskill-compatible system, I would've expected something like adjusting only a secondary global visual rating. The visual rating would be given to clients to protect new players from player-led rating discrimination.

Team balance functions in matchmaker and custom game lobby should ideally be given the real rating, with any UI elements using visual rating, but if that's too difficult then just balancing by visual rating is possible too, since trueskill will calculate the results of such imbalanced non-50/50 games correctly as particularly expected/unexpected outcomes.
In theory there could be problems of players feeling like the game is creating unfair lobbies, but I think that visual rating being used for balance should be ok as it is under the reasonable assumption that matchmaker skill transfers to real games, and if real rating is used for balance then it should adjust close enough to visual rating to create fair lobbies within 10 games.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions