GlickoRatingSystem - Pure Elixir implementation of the Glicko-2 rating system

A pure, zero-dependency Elixir implementation of Mark Glickman’s Glicko-2 rating system for two-player games.

Glicko-2 improves on Elo by tracking two additional quantities per player: a rating deviation (how uncertain the rating is) and a volatility (how erratic the player’s performance is). It is used by Lichess, Counter-Strike 2, Splatoon 2, and many others.

Features

  • Faithful implementation of Glickman’s published algorithm, including the Illinois variant of the regula falsi method for volatility convergence
  • Accepts fractional scores in [0.0, 1.0] — not just win/draw/loss — enabling graded outcomes (e.g. checkmate vs. stalemate)
  • Plain {rating, deviation, volatility} tuples — no structs, no GenServers, no state
  • Pure functions, safe to call concurrently from any number of processes
  • Strict input validation at the boundary with clear error messages
  • Zero runtime dependencies
  • 100% line coverage
  • Supports Elixir 1.14+ / OTP 25+

Quick example

player = {1500.0, 200.0, 0.06}
opponent = {1400.0, 30.0, 0.06}

# Player wins
{rating, deviation, volatility} = GlickoRatingSystem.rate(player, [{opponent, 1.0}])
# rating > 1500.0, deviation < 200.0

# Predict win probability
GlickoRatingSystem.expected_score(player, opponent)
# returns a value > 0.5

Fractional scores

Unlike traditional Elo, Glicko-2 natively supports any score between 0.0 and 1.0. This is useful if your platform differentiates between types of victories. For example, a platform could use:

Outcome Winner Loser
Decisive win 1.0 0.0
Partial win 0.75 0.25
Draw 0.5 0.5

The algorithm is agnostic about the specific values and their meaning — it only requires that both sides sum to 1.0.

Background

I built this for Sashité, a platform for chess, shogi, xiangqi, and related variants. I needed a rating system that could handle graded outcomes without hacking the algorithm. It turned out Glicko-2 supports this natively through its score parameter, so the implementation follows Glickman’s specification with no ad-hoc modifications.

Links

4 Likes