Class ArenaRating
The ranked arena's rating arithmetic. Pure, so it is testable and so the server has nothing to decide when it writes the result.
public static class ArenaRating
- Inheritance
-
ArenaRating
- Inherited Members
Remarks
Elo, team-wise: each player is rated against the average rating of the opposing team(s), and every member of a team gets the same expected score, so a team's carry and its passenger move by the same amount — the result was the team's. The K-factor is larger during placement so a new player's first games move them quickly to where they belong, then settles.
The matchmaking band widens with wait time: a high rating alone in the queue would otherwise never play. The band is measured from the longest-waiting candidate, so it is their patience that opens the field.
Fields
DefaultRating
Rating every character starts a season at.
public const int DefaultRating = 1500
Field Value
MinimumRating
Lowest a rating can fall. Keeps the number meaningful and the board readable.
public const int MinimumRating = 100
Field Value
Methods
Apply(int, int)
Applies a change and clamps to the floor.
public static int Apply(int rating, int delta)
Parameters
Returns
Delta(int, int, double, int)
The rating change for one player from one result.
public static int Delta(int rating, int opponentAverage, double score, int k)
Parameters
ratingintTheir rating before the match.
opponentAverageintAverage rating of everyone on the other side(s).
scoredouble1 for a win, 0.5 for a draw, 0 for a loss.
kintTheir K-factor.
Returns
- int
A signed change, rounded to the nearest point; a win is never worth 0.
Expected(int, int)
Expected score of a rating against an opponent's, in [0,1].
public static double Expected(int rating, int opponentRating)
Parameters
Returns
KFactor(int, int, int, int)
The K-factor for a player: larger while placing, then the template's.
public static int KFactor(int gamesPlayed, int placementGames, int k, int placementK)
Parameters
Returns
OpponentAverage(IReadOnlyList<(int team, int rating)>, int)
Average rating of everyone not on the given team. Returns the default when no one is.
public static int OpponentAverage(IReadOnlyList<(int team, int rating)> members, int team)
Parameters
Returns
PlacementGamesRemaining(int, int)
Placement games left before the rating is shown as final. 0 once placed.
public static int PlacementGamesRemaining(int gamesPlayed, int placementGames)
Parameters
Returns
Resolve(IReadOnlyList<(long characterId, int team, int rating, int games)>, int, int, int, int)
Rating changes for every member of a finished match.
public static List<(long characterId, int delta, int newRating)> Resolve(IReadOnlyList<(long characterId, int team, int rating, int games)> members, int winnerTeam, int placementGames, int k, int placementK)
Parameters
membersIReadOnlyList<(long characterId, int team, int rating, int games)>Each seat: character, team, rating before, games played before.
winnerTeamintWinning team, or -1 for a draw.
placementGamesintGames at the placement K-factor.
kintSettled K-factor.
placementKintPlacement K-factor.
Returns
- List<(long characterId, int delta, int newRating)>
Per character: the change and the new rating, in input order.
ResolveBand(int, int, double, int)
The rating band the matchmaker searches within after a wait.
public static int ResolveBand(int baseBand, int growthPerSecond, double waitedSeconds, int maxBand)
Parameters
baseBandintBand at zero wait. 0 disables banding entirely.
growthPerSecondintPoints the band widens by per second waited.
waitedSecondsdoubleSeconds the longest waiter has waited.
maxBandintCeiling, or 0 for none.
Returns
ScoreFor(int, int)
Score a team earned: 1 won, 0.5 drew, 0 lost.
public static double ScoreFor(int team, int winnerTeam)