How a player’s role is assigned, and how every role-relative number on this site is built from it.
Every role referenced on this site — player cards, Role-Based Stats, and everything below — comes from one of three families: how a player scores, how they defend, and how they create.
Step 1
Everything the role scoring touches is put on a 0–1 scale first, so it can be compared against a hand-written template. A scoring player is described by fourteen numbers:
Playmaking uses five: passes, time of possession, pick-and-roll handler share, isolation share and dribbles per touch. Defense uses five: the four defended-shot frequency ranks (how much of what you are shot at comes from inside 6 ft, inside 10 ft, beyond 15 ft, and from three) plus box-outs.
Traded players are collapsed to a single row before any of this is ranked. Twelve of the fourteen scoring features are percentile ranks against the full league pool, and a player traded mid-season arrives as one row per team plus a combined row. Leaving the duplicates in shifts every rank in the league slightly, which shifts every role score, which shifts every baseline.
Step 2
Each role is a hand-authored vector of target values on those same features. A Rollman is 1.0 on rim frequency, 1.0 on pick-and-roll roll share, 1.0 on assisted twos, 0.1 on three-point frequency. A Movement Shooter is 1.0 on three-point frequency and 1.0 on off-screen share. Scoring a player against a role is one line of arithmetic:
Every player gets a score against all nine scoring roles, all four defensive roles and all four playmaking roles. The visible label is just the highest of them — but the labels are mostly for display. The metrics use the continuous scores, blended across a player’s top two roles, so a player is treated as a mixture (60% Rollman / 40% Cutter) rather than dropped in a bucket.
Step 3
Every “expected” number on the site comes out of one of three routines. All three are single-season: the expectation for 2025-26 is built entirely from the 2025-26 player pool. No prior seasons, no fitted coefficients, nothing carried in from anywhere else.
Nobody is compared to a pool containing themselves. In the first two engines a player’s own attempts and makes are subtracted out of their own role group’s mean before the comparison — a leave-one-out average. Without it, a high-volume outlier drags the baseline they are measured against toward their own number, and quietly shrinks their own residual.
Step 4 · The Headline Number
This is what the method now exists to produce. Shots are bucketed from the full 12-zone shot chart, not from a summary endpoint:
For each bucket, the expected FG% comes out of the volume-weighted engine, weighted by season attempts, with a floor of 20 attempts in that bucket for the season. Then:
This is what drives the Shot Zones tab on Role-Based Stats, the rim, mid and three tiles on player cards, and the offensive grades.
Live from the same table the rest of the site reads. Sort any column. Bars encode the residual; a player under the attempt floor in a bucket shows an em dash there, not a zero.
| Player | GP | Top Scoring Role | Rim FG% | Expected | Rim RFG | Mid FG% | Expected | Mid RFG | 3P FG% | Expected | 3P RFG | O Shot ↓ |
|---|
Percentages shown ×100. RFG bars are clipped at ±12 points of FG%. First 400 rows of the current sort.
Step 5
RFG answers “how well”, not “how much”. A player 6 points above expectation on two rim attempts a game is not doing what a player 6 points above expectation on nine attempts is doing. O Shot is the same three residuals converted to points:
Step 6
| Metric | Peer group | How it is built |
|---|---|---|
| TS Residual | Scoring roles | Actual TS% minus the minutes-weighted TS% of the player’s top two scoring roles, over the 500-plus-minute pool. |
| Role TOV | Playmaking roles | Rate-based, not count-based: turnovers per touch against the expected rate for the role blend, then multiplied back by touches. Floor of 10 touches per game. Turnovers saved per game. |
| Role OREB | Defensive roles | Offensive rebounds per game against the count baseline for the role blend. |
| Role DREB | Defensive roles | Same, defensive rebounds. |
| Role FTA | Scoring roles | Free throw attempts per game against the count baseline for the scoring role blend. |
For turnovers, offensive rebounds and free throws there is a second z-score alongside the residual: a level score, which z-scores the raw stat withinthe player’s role group (falling back to the league distribution when a group holds fewer than 15 players). Turnovers are negated first, so fewer is better. The two are mixed:
| Floor | Value | Applies to |
|---|---|---|
| Season attempts per zone | 20 | Rim / Mid / Three RFG |
| Attempts per game per zone | 0.3 | O Shot, D Shot |
| Touches per game | 10.0 | Role TOV |
| Season minutes | 500 | TS baseline pool |
| Role group size | 15 | Level z-score, before falling back to the league distribution |
| Roles blended | 2 | Every baseline |
A player below a floor is excluded from that metric’s pool, not merely hidden from the table — leaving them in would let non-participants pull the mean the participants are measured against.
Limitations
The baseline is only as good as the role templates, and those are hand-authored judgement calls, not learned. A player who genuinely does not resemble any of the nine scoring archetypes gets a blend of the two least-bad fits.
Because everything is single-season, role assignments can move year to year for a player whose game did not actually change — a shifted shot diet or a team’s scheme change is enough.
Shot quality within a zone is not modelled. Two players with identical rim FG% are treated identically whether the attempts were uncontested cuts or contested drives.
Strengths
It is fully auditable. Every number on the site can be traced to an attempt-weighted average of a specific set of players in a specific season — there are no fitted coefficients to explain and nothing to retrain.
The leave-one-out construction means no player is measured against a baseline they helped set, which matters most at the top of the volume distribution, where a single player can move a role average on their own.
Nothing crosses seasons, so a season’s numbers are stable the moment that season’s data is in, and an in-progress season is internally consistent rather than being compared to a baseline fitted on finished ones.