How a shot on the play-by-play feed becomes the single number on every card. This is the long version of the Reference glossary: each step of the derivation, the constants it uses, and one player worked end to end.
Net goals is how many goals a player adds to, or costs, his team over a season compared with a league-average player in the same role and the same circumstances. It is quoted per 82 games so a 45-game season and a 200-game career sit on the same scale. Positive is good; zero is exactly average.
The first four terms come from one engine: every second a player is on the ice, the model prices the shots his team generates and allows, subtracts what an average lineup would have generated and allowed in that exact game situation, and books the difference to everyone on the ice. The last three terms are individual: they credit the player alone for things only he did. The rest of this page derives each piece.
Everything is built from the NHL’s public game feeds, sixteen seasons of them (2010-11 through 2025-26, roughly 19,100 regular-season games):
Two things the public feed does not contain shape everything downstream: there are no passes and no zone entries. The model sees where a shot came from and what happened in the few seconds before it, never the cross-ice feed that made it dangerous. Section 13 returns to what that costs.
An expected goal (xG) is the probability that a shot attempt becomes a goal, judged only by what the feed knows about it. The model prices every unblocked attempt (shots on goal plus misses, together called Fenwick attempts): about 1.6 million of them over the sixteen seasons, adding up to about 104,900 expected goals, which by construction equals the number of goals actually scored.
The attacking half of the rink is divided into a grid of 2 ft × 2 ft cells. For every season, shot type and strength situation (even strength, power play, and short-handed or extra-attacker play) the model records the share of attempts from each cell that scored, smoothed with a Gaussian of about 3 ft so neighbouring cells inform each other. A slap shot from the point and a backhand from the crease each get their own conversion rate, and those rates are allowed to differ from one season to the next.
Two housekeeping details matter more than they sound. First, the feed reports coordinates in an arbitrary end of the rink, so the model works out which way each team was shooting in each period from the median sign of its own attempts and rotates everything into one frame. An earlier version simply mirrored negative coordinates, which mapped 150-foot clearing flings onto the crease. Second, attempts from outside the blue line are priced with a single long-range rate rather than the grid, because the grid there is too sparse to trust.
Location is not the whole story, so a few pre-shot flags are read off the event sequence and applied as odds multipliers on top of the location rate:
Each multiplier is the ratio of how often flagged shots actually scored to what the location grid alone predicted for them, fit per season because the economics drift hard: an even-strength rebound multiplied the odds by about 3.7 in 2010-11 and by about 0.8 in 2025-26, as goalies learned to smother the second chance. Finally, a per-season scalar nudges every probability so that the season’s xG total equals its goal total exactly. That calibration is what makes 2011 and 2025 comparable on one scale.
Three flavours of xG are used downstream. The on-ice engine (steps 2–4) prices all unblocked attempts with flags. Shooter finishing (step 7) uses shots on goal with flags, which best predicts held-out goals. Goalie work (step 8) uses shots on goal without flags, because a goalie’s rebounds are largely his own leakage and repricing them would excuse the skill being measured.
Not all chances are equal. A tying chance in the last minute matters more than a chance when the game is already 5-1. Net goals prices each shot by how much it would have moved the odds of winning, and the tool for that is a win-probability (WP) table: for every score differential, every game second, and every strength state, the probability that the home team wins.
The table is fit on 2.2 million game states sampled every 15 seconds across the sixteen seasons. The baseline is a logistic curve per score differential in a transformed clock, u = 1 / √(minutes remaining + 1), which is how leads turn into certainties as time drains. On top of it, each non-even strength state shifts win probability by a fixed fraction of a goal, fit by least squares:
| Strength state | γ (net goals expected while it lasts) |
|---|---|
| 5-on-3 | +0.244 |
| Power play (one skater up) | +0.038 |
| Own goalie pulled (extra attacker) | +0.040 |
| Opponent’s goalie pulled | −0.028 |
| Penalty kill (one skater down) | −0.041 |
| 3-on-5 | −0.295 |
A power play in a tied game is worth about 4% of a goal-swing; the same power play when up three with two minutes left is worth nothing, because the goal swing itself is worth nothing then. The state offsets ride on the geometry of the baseline automatically.
The value of a shot is its expected goals times the win-probability jump a goal would have caused at that moment:
The unit is win-probability percentage points; 100 points is one full win. The same 0.10-xG shot is worth very different amounts depending on when it happens:
| Game situation (5-on-5, home team shooting) | WP before | Swing of a goal | Value of a 0.10 xG shot |
|---|---|---|---|
| Tied, 10:00 into the first | 53% | +16.7 pts | 1.7 pts |
| Tied, 5:00 left in the third | 51% | +37.4 pts | 3.7 pts |
| Tied, 1:00 left in the third | 50% | +45.5 pts | 4.6 pts |
| Down one, 5:00 left | 13% | +37.8 pts | 3.8 pts |
| Up one, 5:00 left | 89% | +10.1 pts | 1.0 pts |
| Up three, 10:00 into the third | 99.7% | +0.2 pts | 0.02 pts |
Two consequences follow. Garbage time is nearly worthless, so padding numbers in blowouts does not work. And the engine is results-blind: it prices the chance, never whether the puck went in. A player who scores 50 goals on ordinary chances gets ordinary credit here; his shooting shows up in the separate finishing layer (step 7), so the same goal is never counted twice.
Summing priced shot flow while a player is on the ice would reward deployment as much as play: a first-line forward who starts every shift in the offensive zone with a lead will generate more than a checker who starts in his own end. The fix is to compare every second a player plays against the league-wide average for that exact situation, and only credit the difference.
Every on-ice second is assigned to a context cell defined by five things:
That makes 8,064 cells. For each one the model records, across all sixteen seasons and both teams, how much xG per second was generated by teams in that situation. Thin cells are shrunk toward the same cell with the zone-start dimension pooled away, using 600 pseudo-seconds, so a rarely visited 5-on-3-with-a-neutral-zone-draw cell borrows from its neighbours. The zone-start dimension alone shows why this matters. At 5-on-5 in regulation:
| Ten seconds after… | xG for per 60 min |
|---|---|
| an offensive-zone faceoff | 3.63 |
| open flow (no recent faceoff) | 2.67 |
| a neutral-zone faceoff | 0.45 |
| a defensive-zone faceoff | 0.40 |
An offensive-zone start produces nine times the offense of a defensive-zone start. Without the cell, that gap would be charged to the players; with it, only performance above the deployment baseline counts.
The cell rate is turned into win-probability units the same way a shot is, by multiplying by the goal swing at that second. For each second a player is on the ice, the model knows the expected priced flow for his team and against it:
A player’s game total, called relWPA (relative win probability added), is the sum of his shift credits. Because the baseline is the league average in the same cells, the league as a whole nets to almost exactly zero in every season (the per-player-game mean is +0.08 points against a standard deviation of about 10.9). One deliberate simplification: all five skaters on the ice receive the same credit for each second. Nothing inside this step says who made the pass; that is what the linemate context on the cards, the Chemistry page, and the playmaking research exist to probe.
relWPA is one number per game. The card shows four, and the split is an accounting identity rather than a second model. Every second of every shift is classified along two axes:
Offense and defense are reported separately at even strength; on special teams both directions are folded together into a single PP and a single PK figure, since a power-play unit is judged on the whole exchange. The four pieces sum back to the game’s relWPA with a maximum discrepancy of 0.0006 points across 729,000 player-games.
At this point the on-ice components are in win-probability points and the individual layers (step 7) are in goals. To put them on one scale, the model asks the standings what each is worth. A regression on completed team-seasons relates the roster’s summed inputs per game to the points the team actually earned:
To read those coefficients as goals, one more conversion: a goal per game over 82 games is 82 goals; at roughly six goals per win and two points per win that is 27.3 standings points. So:
The context cells make relWPA nearly zero-mean, but not exactly, and not component by component. The cell rates are pooled over all sixteen seasons and the win-probability pricing is not perfectly symmetric, so within any one season the priced offense sits slightly above the baseline league-wide and the priced defense slightly below it. The two nearly cancel in the total, but a card shows them separately. So, in each season, the league’s total tilt in each component is divided by the league’s total seconds in that situation and removed from every player in proportion to his own exposure:
After this, the exposure-weighted league average of every on-ice component is zero in every season, exactly, which is what “versus a league-average player” promises. The same treatment is applied to penalties (step 7). It changes nobody’s ranking; it moves the offense and defense columns by a fraction of a goal in opposite directions.
The on-ice engine prices chances and shares them. Three things a player does by himself live in outcomes rather than chances and get their own layer, each deliberately independent of the on-ice number.
Goals above expected on the player’s own shots, using the shots-on-goal xG with rebound and rush flags. Because the on-ice engine only ever counted the xG of those shots, finishing is the part it left on the table: a 40-goal season on 28 xG is +12 here and nothing extra in EV offense. Across the sixteen seasons the correlation between a player’s finishing and his on-ice value is −0.02: the two really are separate information.
The price of a drawn minor is measured directly rather than regressed. For every non-offsetting two-minute minor since 2010-11, about 112,000 of them, the model counts goals for the team that drew it minus goals for the team that took it during the next 120 seconds of game time. At even strength that difference would be zero by symmetry, so its average is the value of the penalty. Offsetting minors, which produce 4-on-4, come out at about +0.016, close enough to zero to validate the method. The value rises with power-play conversion, from 0.162 goals per minor in 2011-12 to 0.198 in 2024-25, and each season uses its own. The league’s net is slightly negative every year because some penalties (delay of game, too many men, bench minors) are taken without being drawn, so the league mean per game, about −0.009, is removed before pricing.
A net faceoff win is worth about one-hundredth of a goal, estimated from whether the same team wins by more on nights it wins the faceoff battle (a within-team-season fixed-effects fit, t = 3.6). This is the one component that overlaps the others: possession after a draw is already priced in the on-ice flow of everyone on the ice. It is included at face value so that a center’s card reflects a real skill, and it is small: the top 5% of regular skaters earn about one goal a season from it.
Goalies do not get the seven skater components. Their on-ice relWPA measures the shot flow in front of them, which is the skaters’ property, so a goalie is scored only on what he stops: goals saved above the expected goals of the shots he faced, using the no-flag xG described in step 1. The save-map panel on goalie cards is the same quantity by rink zone, and rebounds yielded per 100 shots is reported alongside because it is the goalie skill that repeats most strongly from season to season.
Every component is stored as net goals per game for each player-season with at least ten games. Displayed values multiply by 82. Career values are games-played-weighted means, so a 20-game cup of coffee counts a quarter as much as a full season.
A career rate built on 60 games is mostly noise, so career numbers on the cards and the Players table are pulled toward the league mean before being called skill. Each component has its own pseudo-game count K, estimated from how much a player’s own rate bounces from season to season versus how much players differ from each other; at K games the career rate is half signal, half prior:
| Component | K (games) | Reading |
|---|---|---|
| EV offense | 52 | a real skill that shows quickly |
| Penalties | 52 | likewise; drawing penalties persists |
| Faceoffs | 44 | very stable per player |
| EV defense | 166 | noisier: needs two seasons |
| Power play | 204 | small minutes per game |
| Finishing | 280 | shooting luck is loud; about 500 shots on goal |
| Penalty kill | 691 | the least trustworthy in small samples |
| Goalie GSAx | 200 | games in net |
Per-season values are never shrunk; they are what happened. Only career cells and the career-based rank rows use the prior.
Every number below is either a raw count from the play-by-play or one of the pinned constants explained above. The right-hand column is what his card and the Players table show for that season.
| Component | Raw input | Arithmetic (net goals per game, then × 82) | NG / 82 |
|---|---|---|---|
| EV offense | +729.2 WP points of priced shot flow over 71,432 even-strength seconds | (+729.2 − 0.00081×71,432) ÷ 100 ÷ 67 × 1.24 × 82 | +10.3 |
| EV defense | -65.0 WP points (opponent flow, sign flipped) | (-65.0 − (-0.00075)×71,432) ÷ 100 ÷ 67 × 1.24 × 82 | -0.2 |
| Power play | +112.8 WP points over 15,341 PP seconds | (+112.8 − 0.00241×15,341) ÷ 100 ÷ 67 × 1.24 × 82 | +1.2 |
| Penalty kill | +19.1 WP points over 1,793 PK seconds | (+19.1 − (-0.00241)×1,793) ÷ 100 ÷ 67 × 1.24 × 82 | +0.4 |
| Finishing | 26 goals on 28.1 xG from 196 shots on goal → GAx -2.1 | -2.1 ÷ 67 × 0.94 × 82 | -2.4 |
| Penalties | 23 drawn, 12 taken → net +11; league mean -0.009/game | (+11 − (-0.009)×67) × 0.198 ÷ 67 × 82 | +2.8 |
| Faceoffs | 370 won, 406 lost → net -36 | -36 × 0.010 ÷ 67 × 82 | -0.4 |
| Overall | sum of the seven | +11.5 |
Components are rounded to one decimal after the arithmetic; the Overall is summed before rounding. The subtraction in each on-ice row is the season re-centering described in step 6: league-wide, even-strength offense priced about 0.0008 WP points per second above the context baseline in 2024-25, so 57 of his 729 points are the league’s tilt, not his.
Because the scale is anchored to the league average with heavy-minute players weighted more, the typical regular is slightly below zero. The distribution of Overall net goals per 82 among the 612 skaters with 40 or more games in 2025-26:
| Percentile | 5th | 25th | Median | 75th | 90th | 95th | 99th | Best |
|---|---|---|---|---|---|---|---|---|
| Overall NG / 82 | −7.3 | −3.6 | −0.7 | +3.0 | +8.0 | +10.8 | +16.3 | +23.8 |
A rough guide: +3 is a good regular, +8 is a first-liner or top-pair defenseman, +10 and up is an All-Star season, and +15 or more is a handful of players in a given year. Six goals is about one win in the standings, so a +12 season is worth roughly two wins over an average player in the same minutes. The components have very different spreads: finishing (standard deviation about 4 goals per 82) and EV offense (about 1.9) move the Overall most; the penalty kill (about 0.6) rarely does.
See also: How to Read a Card for where each of these pieces appears on a card, and the Reference glossary for one-paragraph definitions.