Annex: Statistics model — XG / gnuBG / blunderDB alignment

This page describes how blunderDB computes the figures it displays — PR (Performance Rating), Snowie Error Rate, MWC loss, luck and wins/losses — and how they line up with eXtreme Gammon (XG) and gnuBG (the open reference).

Formal definitions

PR (Performance Rating)

PR (also called “error rate per decision” in gnuBG) measures the average cost of errors per counted decision, on the eXtreme Gammon and gnuBG scale: the average equity error, multiplied by 500.

\[\mathrm{PR} = \frac{\sum_i |\mathrm{error}_i|}{\mathrm{N_{counted}}} \times 500\]
  • The numerator is the absolute sum of EMG errors (cubeful equity) over all decisions in the scope.

  • The denominator \(N_\text{counted}\) is the number of counted decisions (see below).

  • The factor of 500 is the XG and gnuBG convention (see gnubg/formatgs.c:399–409). It is not a conversion into millipoints: an average equity error of 0.010 — that is 10 millipoints (mpt) — gives a PR of 5.0. A position’s own errors, by contrast, are read directly in millipoints, i.e. thousandths of equity: the blunder threshold below, the e> and E> search filters, the magnitude histogram in the Stats panel.

Snowie Error Rate

Snowie ER uses the same numerator as PR, but the denominator is the total number of moves of both players, forced moves included (all decisions, no filter):

\[\mathrm{SnowieER} = \frac{\sum_i |\mathrm{error}_i|}{N_\text{P1} + N_\text{P2}} \times 500\]

Reference: gnubg/formatgs.c:415–424.

Snowie ER is more stable across tools because its denominator does not depend on the forced/trivial decision filter. It serves as a cross-check metric between XG, gnuBG, and blunderDB.

Important

The “Player” filter applies to the numerator only. Selecting a player restricts the summed errors to that player’s own decisions, but the denominator stays the number of checker plays by both players, over the matches the filter retains. This is what sets the Snowie ER apart from the PR, and the reason for the following property: on a database holding only matches between two players, the sum of their two Snowie ERs is exactly the unfiltered Snowie ER.

Note

A player’s Snowie ER is typically about half their PR, because the denominator includes moves from both players while PR only uses that player’s decisions.

MWC loss (Match Winning Chance)

MWC loss expresses in percentage points of match-winning probability the cumulative effect of a player’s errors. For each decision, the EMG error is converted to MWC using the MET (Match Equity Table) at the current score:

\[\mathrm{MWCLoss} = \sum_i \mathrm{eq2mwc}(\mathrm{erreur}_i, \mathrm{score}_i)\]

Reference: gnubg/analysis.c:1449–1464.

Luck

The luck of a roll is the gap between what the dice gave and what they give on average:

\[\mathrm{luck} = \mathrm{eq}(\text{best play with the roll obtained}) - \frac{1}{36}\sum_{d} \mathrm{eq}(\text{best play with } d)\]

the sum running over the 36 outcomes of the roll (30 non-double rolls for the opening play of a game, which cannot be a double). A positive value means a favourable roll. Reference: gnubg/analysis.c:199–269 (LuckNormal / LuckFirst, cubeful evaluation at 0 ply).

Important

blunderDB never recomputes luck: the built-in evaluator is not used for that. It takes verbatim the value written by the tool that analysed the match — ErrLuck for eXtreme Gammon, the LU property for gnuBG — having checked that both share the same convention (same unit, positive = lucky).

Practical consequences:

  • Formats that do not carry luck (BGF, Jellyfish .mat) produce no value at all.

  • Matches already imported have none either: luck was never stored before schema version 2.15.0, and nothing in the database allows it to be reconstructed. The source files must be re-imported to obtain it.

  • A missing value means unknown, never zero — zero is a genuinely neutral roll. Luck averages therefore divide only by the number of rolls whose luck is known.

  • A match in which every roll would have exactly zero luck is treated as unanalysed in that respect (eXtreme Gammon writes 0 both for “neutral” and for “not computed”): its rolls stay unknown. On the gnuBG side the distinction is explicit — an unevaluated roll carries LU[-inf] — and those rolls stay unknown as well, rather than being turned into a value.

Wins and losses

blunderDB stores no winner at match level: only the points of each game are stored. The result is therefore derived at display time, by adding up the points per seat:

  • N-point match — winner = the player who reaches N. If nobody does, the match is unfinished (truncated log, resignation) and counts neither a win nor a loss, for anybody.

  • Money game (no target) — winner = whoever took the most points; on a tie, neither a win nor a loss. This is gnuBG’s session-result convention (+1 / 0 / −1, gnubg/relational.c).

A consequence to keep in mind when reading the Players tab: wins + losses can be lower than the number of matches. The gap is the unfinished matches.

Errors and blunders

A decision counts as an error as soon as the associated equity error reaches the library’s error threshold, and as a blunder as soon as it reaches its blunder threshold. Both are set in the Library tab of the settings and are 0.050 and 0.100 EMG (50 and 100 millipoints) by default. The comparison is inclusive: an error of exactly 0.100 is a blunder at the default threshold, on every screen (breakdown by cube action, match detail, players table), and the same pair serves the status bar’s counter and the list offered after an import.

These thresholds belong to each library, and the default values are blunderDB’s own: gnuBG grades plays in three steps (0.03 doubtful, 0.06 bad, 0.12 very bad — gnubg/gnubg.c:281–286) rather than in a single category, and eXtreme Gammon draws its own at 0.020 and 0.080. Both are offered as presets.

Decisions counted in the PR denominator

blunderDB follows the same exclusion rules as XG and gnuBG.

Checker plays — counted decisions

Only unforced moves are counted:

  • A move is forced if the dice offer only one legal play (cMoves == 1 in gnubg/analysis.c:458).

  • Forced moves have zero error by definition: the player had no choice. Including them in the denominator would artificially lower PR.

Cube decisions — counted decisions

Only close cube decisions are counted:

  • A cube decision is close if it lies within the equity window [-0.16, +0.16] around the doubling point (predicate isCloseCubedecision in gnubg/eval.c:5088–5100).

  • A trivial No Double (very negative or very positive equity) is not a genuine strategic decision; including it would inflate the denominator and depress PR.

Filter summary

Decision type

Included in \(N_\text{counted}\) (PR)

Unforced move

Yes

Forced move

No

Close cube

Yes

Trivial No Double

No

Take / Pass

Always (these are responses to a double)

blunderDB ↔ XG ↔ gnuBG correspondence

The metrics are aligned within the limits below. These are bounds checked by the test suite, not average gaps: the test compares blunderDB’s figures to those recorded for the repository’s reference matches, match by match, and fails as soon as a single gap exceeds the bound. The XG references cover two matches — one complete (317 counted decisions, 156 and 161 per player), the other reduced to its PR alone, with a bound raised to 0.15 because of one unmatched move; the gnuBG references cover two other matches. The version of eXtreme Gammon that produced these figures is not recorded.

XG ↔ blunderDB comparison (same analysis engine)

Metric

Maximum gap

Total decisions

≤ 5

Unforced moves

≤ 7

PR

≤ 0.10

MWC loss

≤ 1.0 pp

Total equity (EMG)

≤ 0.05

gnuBG ↔ blunderDB comparison (SGF import — different engines)

Metric

Maximum gap

Main cause

PR (checker)

≤ 0.20

cross-engine equity differences

MWC loss

≤ 3.5 pp

incomplete close-cube data in SGF

Snowie ER

≤ 0.50

forced moves without analysis (SGF)

Note

SGF files (gnuBG) do not include alternatives for forced moves, which means blunderDB cannot detect all forced moves when importing SGF. This creates a structural gap on Snowie ER (slightly different denominator).

Validating your own figures

If your PR or MWC values diverge from XG figures, check the following points:

  1. Complete analyses — PR can only be computed on positions that have an analysis. Positions without analysis count as zero error but are not included in \(N_\text{counted}\).

  2. XG version — XG may change its calculations between versions. blunderDB is aligned with the behaviour observed in recent versions.

  3. Import format — gnuBG SGF files produce larger gaps on cube metrics (see table above) because the file does not include complete analyses for all cube decisions.

  4. Database migration — After updating blunderDB, existing databases are migrated automatically. Make a backup before opening a database with a new version.

gnuBG reference

Formulas have been verified against the following source files (gnuBG repository):

  • gnubg/formatgs.c:399–409 — PR (“Error rate per decision”).

  • gnubg/formatgs.c:415–424 — Snowie Error Rate.

  • gnubg/analysis.c:458–462 — Checker accumulation, exclusion of forced moves (cMoves > 1).

  • gnubg/analysis.c:1430–1474 — Per-decision EMG → MWC conversion.

  • gnubg/analysis.c:1449–1464 — MWC loss accumulation (eq2mwc).

  • gnubg/eval.c:5088–5100 — isCloseCubedecision predicate (0.16 threshold).