Net Rating, in full
Net Rating is goals above average over an 82-game season, for skaters. It splits a player's value into offense and defense and measures each against other players at his position.
None of this exists without Dom Luszczyszyn. Net Rating is his: the Game Score split, the position-specific weights, the per-team pace adjustment and the goals-above-average scale, first as GSVA and then in the 2019 formula. What we built is an implementation of his idea on our own data. Where we departed from him we say so and say why. The ice-time pace adjustment on the defensive side was his suggestion to us; we measured it and it held up. Dropping his quality-of-competition multiplier was our own call, after testing.
How it is built
Net Rating starts from Game Score, a box-score credit for goals, assists, shots, blocks and penalties. It is split into an offensive half and a defensive half. Each half then adds an on-ice term: the shot chances (xG(sh)) and goals that happened with the player on the ice, compared with what we would expect for his team over his minutes. Forwards and defensemen carry different weights.
Each half is measured against the average game played at the same position, converted into goals, and projected to 82 games. The formulas and weights are in the appendix.
This follows Dom Luszczyszyn's 2019 overhaul of his Game Score system, published in The Athletic, with the changes described below.
Where players land
Net Rating is goals above average over an 82-game season. The average is taken over games, not over players: zero is what an average game at the position is worth. Regulars play most of the games, so zero is not the middle skater, and where the middle falls depends on who is counted. Here is how the league's skaters spread out.
Loading…
Worked example
The formula, with the numbers in. Two ledgers: the season's top forward, and the defenseman in the top 50 with the best defensive rating. Every line is an input times a weight, in goals. The lines add to the subtotals; the subtotals, stretched to 82 games, are the rating. Nothing is left over.
Loading…
Forwards earn most of their rating on the scoresheet. Defensemen earn theirs on the xGA(sh) line, where the position weight is heaviest.
Offense vs defense decomposition
Each dot is a skater, with offense across and defense up. Forwards (blue) spread along the offense axis and defensemen (red) along the defense axis. The top right is the rare two-way driver.
Loading chart…
Top 200 skaters by Net Rating, 2025–26, at least 20 GP. Goalies are not included.
Per-team pace adjustment
Teams do not create chances at the same rate, so a player’s on-ice numbers are compared with what we would expect for his team as well as the league: half the league rate, half his team’s. Each bar is a team’s 5v5 xGF(sh) per game this season; the red line is the league average.
Loading…
A skater on a team near the top has a higher bar to clear before his on-ice numbers count as above average; a skater near the bottom has a lower one. This moves every player on a team together. The ice-time adjustment below is separate and individual.
What we changed from Dom
Two departures from the 2019 formula.
We dropped the quality-of-competition and quality-of-teammates multiplier from our first version. We tested it against next-season predictions and it did no better than leaving it out. It also charged stars for having good linemates.
Why we dropped it: the test and what it found
Our first version carried a per-game context multiplier of our own construction: credit nudged up when a player’s opponents were more heavily used than his teammates, both measured by share of ice time, and trimmed when the opposite was true. It was our reading of the idea that some minutes are harder than others. It was not Dom’s own difficulty measure, which is built differently and rates players differently. We shipped it, flagged the coefficient as hand-set and provisional, and said we’d calibrate it properly. We did — and it didn’t survive the test.
Three separate tests, all pointing the same way. Dropping the multiplier equalled or beat keeping it on every individual predictive target we checked. It improved next-season team goal-differential prediction, .612 to .617, with a bootstrap confidence interval that excludes zero. And it moved the league mean of team rating sums from −5.5 toward the theoretical zero, landing at −2.1. Doubling the multiplier’s strength made every one of those numbers worse — which is the signature of an adjustment that adds noise rather than signal, not one that’s merely under-tuned.
It also failed on inspection. Teammate quality varies over a much wider range than competition faced, and a star’s linemates are fixed for stretches of a season while his opponents average out over it. Our multiplier scored difficulty as opponents’ ice-time share minus teammates’. Nathan MacKinnon’s opponents were heavily used (the 76th to 97th percentile of forwards from 2021-22 to 2025-26), but his linemates were used even more (98th to 100th), so the multiplier ranked his job among the easiest: the bottom 1% of forwards in every season from 2021-22 to 2024-25, and the 5th percentile in 2025-26. It was charging him for having good linemates, a thing his rating already counts as their production, not a debt against his own. That is not a small edge case; it is what the multiplier does to exactly the players it is supposed to be fairest to. Today’s rating uses no such measure; the ice-time pace adjustment below replaced it.
That test was of our multiplier, not of the idea. So we tested the idea again, in September 2026, with a design written down before any result existed. Dom Luszczyszyn shared with us an updated weight set and his own context adjustment. The adjustment splits quality into offense and defense rather than using share of ice time, since a defensive-role player and an offensive-role player can log similar minutes against very different matchups. Teammate quality is measured against the teammate quality expected from how good the player and his team are, and only the difference is used, which strips out what the rating already carries from good linemates. The effects of competition and teammates are fitted game by game (a faint signal, over many games, that weaker competition raises a player’s Game Score) and applied as a per-game adjustment. For past seasons the ratings are run once unadjusted and once adjusted; during a season the adjustment is iterated. We rebuilt that approach as closely as our data allowed. Our reconstruction does not yet reproduce the worked examples we were given, so what follows is a finding about our version of the idea, not about anyone else’s method.
The updated weights lost: they read forwards slightly better and defensemen worse, and the defense cost was the larger. The context question was whether a player coming off a good situation, with strong linemates and soft opposition, is overrated the next season. For forwards he is; for defensemen we found no such effect. Our version of the adjustment rates each teammate and opponent from games without the player in question, and is iterated until the ratings settle. On our own weights it removed about 34% of the forwards’ carried-over credit (90% interval 19% to 97%). But it predicted next season slightly worse, for players and for teams, and it agreed slightly less with a competition-matched measure of how players did against opponents of similar quality. In the first round, on the updated weight set, a single-pass version built the other way, with context rated from other nights rather than other players, removed only about 16%, so the size of the effect depends on how context is measured. So the rating keeps the ice-time pace adjustment below and carries no quality-of-competition adjustment.
We added an ice-time pace adjustment, on defense only. A player who plays heavy minutes faces faster, stronger competition, so the chances we expect against him rise 2.11% per extra minute of 5v5 ice time for a forward and 1.25% for a defenseman, above his position’s average. The idea is Dom’s; we measured it before adopting it. The worked example above shows it as its own line. It also means a player who slides down the lineup gets no credit for the easier minutes: the bar drops with the minutes, so the credit does too.
The credit is real but small: about 5 points of Net Rating from best to worst in 2025-26, which is not enough to reorder the league.
Why it holds up, and where it is weak
A player’s expected on-ice chances against now scale with his own 5v5 ice time. That is distinct from the per-team pace blend above: that one anchors a player’s baseline to his team’s scoring rate; this one anchors his defensive baseline to his own deployment. Bigger minutes are faster minutes: top-line players face other top lines, fourth-liners face other fourth-liners, and the chances-against expectation should reflect that before we count what a player did about it.
The whole argument is that the effect being adjusted for is the environment, not the player. Using player fixed effects across those 9,423 player-seasons, when the same player’s ice time changes, his on-ice xGA(sh)/60 relative to team moves by 88% (forwards) to 100% (defensemen) of the gap you’d see comparing different players at different ice times. An independent event study on the ~870 players whose ice time moved 1.5+ minutes within the same team gives 0.75–1.05 — the same range, from a different design. The constant is measured from within-player variation, not inferred from comparing different players who might simply differ in ways the model doesn’t see.
The chances-for side is deliberately left untouched. Only about two-thirds of the ice-time-vs-pace relationship on offense is environment; the rest is that better offensive players earn the bigger minutes in the first place. Adjusting for it would take away credit those players earned. Offense stays exactly as it was, bit for bit.
Caveats, stated plainly:
- Defensemen come out slightly over-corrected. Their within-player slope is a shade steeper than the across-player one used to set the constant, and it shows: Def now correlates +0.13 with ice time for defensemen, versus 0.00 for forwards. That’s within noise, and we’re watching it rather than re-fitting on a single observation.
- The constant is refit annually on the pooled panel, not per season — a per-season refit adds more noise than it removes. Leaving any single season out of the panel moves the constant by about 10%, which is the honest size of its uncertainty.
- Tied to the current xG model. Both percentages above were measured against the shooter-adjusted xG model as it exists today. An xG model change requires remeasuring them.
What to be careful about
- The defensive half is the noisier half. Blocks and penalties are small numbers per game, and on-ice defense is noisier than offense at the season level.
- Defensemen run slightly over-corrected by the ice-time adjustment. It is within noise and we are watching it; the details are in the caveats above.
- Part of the number travels with the team. When a player changes teams, Net Rating predicts his next season worse. For forwards, its correlation with next-season 5v5 goal differential (relative to team) is .39 for players who stayed and .29 for players who moved. The on-ice part of the rating never travels better than the individual part, and in three of the four comparisons it travels substantially worse, up to twice as badly (share of signal lost, on-ice against individual: next-season goal differential, forwards 41.5% against 19.7%, defencemen 37.0% against 28.5%; next-season points, forwards 15.5% against 15.4%, defencemen 26.3% against 13.4%). A player and his team never move apart while he stays, so a trade is the one natural experiment that separates them, and it says the on-ice part is the part that belongs partly to the team.
Formulas, weights and the April check
Reference material. Each drawer opens on its own.
The formulas, step by step
Step 1: Game Score split
Each player's per-game Game Score is divided into offensive and defensive components before any further scaling. The split uses Dom's published weights:
individual_off_gs = 0.75·G + 0.7·A1 + 0.55·A2 + 0.075·SOG + 0.15·iPenDrawn individual_def_gs = 0.05·iBLK − 0.15·iPenTaken
One known difference from Dom's 2019 update: it replaced individual shots with individual expected goals. We still use 0.075 per shot on goal, the weight from the model he updated. We tested the swap and kept shots. Unadjusted expected goals, weighted to keep the term the same size, predicted next season's goal differential no better within a position, including for players who changed teams, and predicted next season's points slightly worse. The 2019 article's own weights did worse: they pulled team ratings out of line with team goals (a team-sum slope of 0.78, against 0.87 now) and cost defencemen about three times what they cost forwards on points.
The 0.01 faceoff term in classic Game Score is left out. We record every faceoff with its winner and loser and publish faceoff percentage, but the term wants each player's wins minus losses in each game, and we do not compute that per-game differential. It is a small term at a 0.01 weight. A flat 0.01 per draw treats an offensive-zone and a defensive-zone draw alike, which matters in principle. Faceoffs are not ignored on the site: the Quick Draw badge rates a centre's draws against the opponents he faced, weighted by what each draw was worth, and that rating still correlates 0.97 with raw faceoff percentage, reordering almost nobody.
Step 2: On-ice play-driving (5v5)
On-ice shot-quality numbers are converted to residuals by subtracting an expected value that blends league average and team pace in equal measure:
expected_xgf = (0.5·league_xgf60 + 0.5·team_xgf60) · TOI/3600 rel_xgf = on-ice xGF(sh) this game − expected_xgf (same form for gf, xga, ga)
Using the 50/50 blend anchors each player's baseline to their team's actual pace rather than a league-wide constant, which satisfies Dom's third adjustment. The same residual form is computed for raw goals-for, expected goals-against, and raw goals-against. Position-specific weights are then applied to these four residuals to combine them into an on-ice contribution score.
expected_xga and expected_ga, the against-side pair only, carry one further scaling beyond the team-pace blend: an ice-time pace factor described under “What we changed from Dom”, which raises the expectation for players who play heavier minutes than their position average. expected_xgf and expected_gf are untouched by it.
Step 3: Per-game scaling and season aggregation
Individual and on-ice components are merged into per-game offensive and defensive ratings, then projected to an 82-game season:
Off_RTG/g = (off_gs_game − pos_off_avg) × 0.75 / (totalGS / totalGoals) Def_RTG/g = (def_gs_game − pos_def_avg) × 0.78 / (totalGS / totalGoals) Net_RTG/g = Off_RTG + Def_RTG Net_RTG (season) = Σ Net_RTG/g · 82 / GP
The position baseline (pos_off_avg, pos_def_avg) is the mean per-game Game Score across all forwards or all defensemen with at least 10 games played that season, computed separately for each side. Subtracting it converts raw Game Score into a value above average. Dividing by the league's Game Score per goal (the worked example shows the current value) translates the result into goal-denominated units. Dom's 0.75 and 0.78 scalars are applied to the offensive and defensive sides respectively, reflecting his finding that the defensive side required a modest upward adjustment to balance contribution. Each per-game rating is summed over all games played and then multiplied by 82/GP to project the cumulative total to a full season.
Position weights
The four on-ice residuals (rel_xgf, rel_gf, rel_xga, rel_ga) receive position-specific weights before being summed into offensive and defensive scores. Forwards and defensemen are weighted differently.
| Position | xGF(sh) | GF | xGA(sh) | GA |
|---|---|---|---|---|
| Forward | 0.625 | 0.625 | 1.75 | 0.4375 |
| Defense | 1.7 | 0.425 | 2.3 | 0.575 |
on_ice_off_gs(F) = 0.625·rel_xgf + 0.625·rel_gf on_ice_def_gs(F) = −1.75 ·rel_xga − 0.4375·rel_ga on_ice_off_gs(D) = 1.7 ·rel_xgf + 0.425 ·rel_gf on_ice_def_gs(D) = −2.3 ·rel_xga − 0.575 ·rel_ga
The defensemen's defensive weights (−2.3 for xGA, −0.575 for GA) are the largest in the formula.
Check against Dom's published ratings (April 2026, not the current formula)
In April 2026 we fitted regression models to reproduce Dom's published season offense and defense ratings from season totals. The models were fitted on 80% of 767 player-seasons and scored on the other 20%, the rows counted in the n column. The table shows that his numbers can be recovered from public inputs.
It does not compare the current ratings with his. The live formula uses fixed weights, and both the QoC/QoT retirement and the ice-time pace adjustment came after this exercise.
| Group | R² (held out) | MAE (held out) | n held out |
|---|---|---|---|
| Forwards, offense | 0.83 | 1.89 | 102 |
| Forwards, defense | 0.25 | 1.64 | 102 |
| Defensemen, offense | 0.80 | 1.78 | 53 |
| Defensemen, defense | 0.57 | 2.47 | 53 |
The defensive halves reproduce worse, which is consistent with defensive Game Score components (blocks, penalties) being small and noisy from season to season.