PHPackages                             elijahcruz12/glicko2 - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. elijahcruz12/glicko2

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

elijahcruz12/glicko2
====================

A modern PHP 8.4 implementation of the Glicko-2 rating system, and the only one on Glicko.net

1.0.1(1mo ago)10MITPHPPHP ^8.4

Since Apr 6Pushed 1mo agoCompare

[ Source](https://github.com/elijahcruz12/glicko2-php)[ Packagist](https://packagist.org/packages/elijahcruz12/glicko2)[ RSS](/packages/elijahcruz12-glicko2/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

glicko2
=======

[](#glicko2)

A modern PHP 8.4 implementation of [Glicko-2](https://en.wikipedia.org/wiki/Glicko_rating_system), a rating system for competitive game ladders. Glicko-2 is a refinement of the well-known [Elo](https://en.wikipedia.org/wiki/Elo_rating_system) rating system that adds the concepts of rating deviation, volatility, and rating decay.

This is a clean, ground-up rewrite targeting PHP 8.4, with full type safety, immutable value objects, and a stateless calculator. It implements the algorithm as described in the [official Glicko-2 paper](https://www.glicko.net/glicko/glicko2.pdf) by Professor Mark E. Glickman (revised March 22, 2022), including the corrected Illinois algorithm for volatility convergence.

This library is linked to on the [official Glicko-2 page](https://www.glicko.net/glicko.html) as a reference implementation.

Requirements
------------

[](#requirements)

- PHP 8.4+

Installation
------------

[](#installation)

```
composer require elijahcruz12/glicko2
```

Usage
-----

[](#usage)

### Creating a player rating

[](#creating-a-player-rating)

For new players, use the default values. The `tau` system constant should be between `0.3` and `1.2` depending on the application, and must be determined by estimation or experimentation. Smaller values prevent large swings in volatility.

```
use Elijahcruz12\Glicko2\Rating;

// New player with defaults
$player = new Rating;

// Existing player with known values
$player = new Rating(
    rating: 1500,
    rd:     200,
    sigma:  0.06,
    tau:    0.5,
);
```

### Calculating updated ratings

[](#calculating-updated-ratings)

Ratings are calculated at the end of a **rating period** — a collection of games treated as having occurred simultaneously. The `Glicko2` calculator is stateless and returns a new `Rating` instance without mutating the original.

```
use Elijahcruz12\Glicko2\Glicko2;
use Elijahcruz12\Glicko2\MatchResult;
use Elijahcruz12\Glicko2\Outcome;
use Elijahcruz12\Glicko2\Rating;

$alice   = new Rating(rating: 1500, rd: 200, sigma: 0.06, tau: 0.5);
$bob     = new Rating(rating: 1400, rd: 30,  sigma: 0.06, tau: 0.5);
$charlie = new Rating(rating: 1550, rd: 100, sigma: 0.06, tau: 0.5);
$david   = new Rating(rating: 1700, rd: 300, sigma: 0.06, tau: 0.5);

$calc = new Glicko2;

// Alice beat Bob, lost to Charlie, lost to David
$newAlice = $calc->calculate($alice, [
    new MatchResult($bob,     Outcome::Win),
    new MatchResult($charlie, Outcome::Loss),
    new MatchResult($david,   Outcome::Loss),
]);

echo $newAlice->rating; // 1464.06
echo $newAlice->rd;     // 151.52
echo $newAlice->sigma;  // 0.05999
```

### Players who did not compete

[](#players-who-did-not-compete)

Pass an empty results array. The rating and volatility remain unchanged, but the RD increases to reflect growing uncertainty.

```
$newDavid = $calc->calculate($david, []);
```

### Outcomes

[](#outcomes)

```
Outcome::Win
Outcome::Loss
Outcome::Draw
```

Serialization
-------------

[](#serialization)

`Rating` implements `JsonSerializable` and supports PHP's native `serialize()`/`unserialize()`, making it suitable for storage in a database or use with Laravel Queues.

### JSON

[](#json)

```
// Serialize
$json = json_encode($rating);
// {"rating":1500,"rd":200,"sigma":0.06,"tau":0.5}

// Restore from JSON string
$rating = Rating::fromJson($json);

// Restore from array (e.g. from a decoded JSON column)
$rating = Rating::fromArray($data);
```

The derived internal properties `mu` and `phi` are excluded from serialization — they are always recomputed from `rating` and `rd` on construction, so round-tripping through JSON is lossless.

### Native PHP serialization

[](#native-php-serialization)

```
$serialized = serialize($rating);
$rating     = unserialize($serialized);
```

### Laravel

[](#laravel)

For storing a player's rating in a database column, a simple JSON cast works well:

```
// In your migration
$table->json('rating_data')->nullable();

// In your model
use Elijahcruz12\Glicko2\Rating;

protected function rating(): Attribute
{
    return Attribute::make(
        get: fn (?string $value) => $value ? Rating::fromJson($value) : new Rating,
        set: fn (Rating $value)  => json_encode($value),
    );
}
```

For Laravel Queues, `Rating` can be passed directly as a job property — PHP's native serialization handles it automatically.

```
class UpdatePlayerRating implements ShouldQueue
{
    public function __construct(
        public readonly Rating $currentRating,
    ) {}
}
```

Concepts
--------

[](#concepts)

**Rating (`r`)** — The player's skill estimate. Defaults to `1500` for new players.

**Rating Deviation (`RD`)** — Uncertainty in the rating. High for new or inactive players, lower for active players with consistent results. Defaults to `350`.

**Volatility (`σ`)** — How erratic the player's performance is expected to be. Defaults to `0.06`.

**System Constant (`τ`)** — Constrains how much volatility can change per rating period. Recommended range is `0.3`–`1.2`. Defaults to `0.75`.

Rating periods
--------------

[](#rating-periods)

Glicko-2 works best when each rating period contains a moderate number of games — ideally at least 10–15 per player. All games within a period are treated as simultaneous. The length of a rating period is left to the administrator's discretion.

Testing
-------

[](#testing)

Tests are written with [PestPHP](https://www.glicko.net/glicko.html) and cover the full algorithm against the numerical example from the official Glicko-2 paper, including intermediate values for `v`, `Δ`, and `σ′`, as well as serialization round-trips.

```
composer require --dev pestphp/pest
./vendor/bin/pest
```

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance90

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3cd86be6ae99ffef0c65552b89e188d783330f4f33af68e9b7a08dc1fd60ee77?d=identicon)[elijahcruz12](/maintainers/elijahcruz12)

---

Top Contributors

[![elijahcruz12](https://avatars.githubusercontent.com/u/14031707?v=4)](https://github.com/elijahcruz12 "elijahcruz12 (3 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/elijahcruz12-glicko2/health.svg)

```
[![Health](https://phpackages.com/badges/elijahcruz12-glicko2/health.svg)](https://phpackages.com/packages/elijahcruz12-glicko2)
```

###  Alternatives

[krisseck/detect-cms

PHP Library for detecting CMS.

9225.1k](/packages/krisseck-detect-cms)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
