RotoProphet

Reference

Models

Every projection or rating model built against this dataset — what it predicts, how it works, how it was checked against real outcomes, and how it stacks up against the alternatives that were tried. Not everything here is live: some are validated but not yet shipped, and one is a dormant system kept for reference.

LiveValidated, not shippedResearch prototypeDormant / legacy

1.Availability — can he play?

How many of the games in the window he is actually available for. Runs first and depends on nothing else: his own history only, no team input. Run across the whole roster, it also supplies "who is available" to the next step — which is why there is no separate teammate model.

ModelPredictsHow it worksAccuracyCompared against / best performer
Games-Played Projection
Live
How many of the remaining games of a season a player actually suits up for. Over short windows it deliberately predicts nothing beyond "he plays" — see below.The player's own recency-weighted history of games actually played, shrunk toward the league average, plus a hard override when a specific return date is known for an injury. Age is not used: durability barely correlates with it, and adding an age term measurably made predictions worse.Over a full season, 43% more accurate than the "assume he plays every game" baseline — the assumption every projection made before this existed. Over the next 5, 10 or 15 games, nothing beats that baseline, so the model does not try: roughly 87% of rostered players genuinely do play every one of their next five games, so "he plays them all, minus any ruled out by a known injury" is both the most likely outcome and the most accurate one.An earlier version of this model did apply a rate over short windows too, on the strength of a test that appeared to beat the baseline at every window. That test was scored partly against players who had joined their team mid-season and so could not have played the games in question — about a quarter of its sample. Corrected, the short-window rate model loses, and it was removed. It was projecting the average player for 2.8 of his next 5 games; the real figure is about 4.4.

2.Opportunity — how much does he get to do?

Minutes on court, and how many chances those minutes carry: shots, touches, rebounding chances. The only step where players are coupled to each other, because a team has just 240 minutes and a limited number of shots, so opportunity is shared and has to be settled for the whole roster at once.

ModelPredictsHow it worksAccuracyCompared against / best performer
Shot-Attempt Opportunity (FGA)
Live
How many field-goal attempts a player gets per 36 minutes, published as its own projected number rather than only as a by-product of the FG% record.Three parts. A crowding term for the change in how much his teammates shoot, priced at what everyone had done BEFORE the season so it is a change in who he plays with rather than hindsight. An allocation that splits the team's shots across the rotation so they are conserved exactly — join a roster of high-volume shooters and your share falls with no crowding coefficient anywhere. And a projected team total, which turns out to travel with the players a team assembles far more than with the team itself.4.25% better than assuming last season repeats, winning all 20 held-out splits. Worth roughly three quarters of everything the points projection has gained.Validated by rebuilding the identical term from REBOUNDING — a skill nobody competes with a shooter for. That version cannot beat the baseline at all, which is the test that separates a real effect from roster churn. Several stronger-looking versions were falsified along the way, including one where five random ranking keys scored the same as the real one.
Free-Throw-Attempt Opportunity (FTA)
Live
Trips to the free-throw line per 36 minutes.Built from foul-drawing history, the share of his shots taken at the rim (a share, not a count — so it separates 'shoots less' from 'stopped attacking the basket'), his projected shot attempts, and a crowding term of its own.About 2% better than carrying free-throw attempts forward, all 20 splits. Correct on 20 of 28 players across three named roster shake-ups — better than the shot model manages on the same cases.The finding that made it work: free throws are crowded by teammates who DRAW FOULS, not by teammates who shoot. Borrowing the shot-crowding term instead is measurably worse. The rebound-built placebo is worse than having no crowding term at all.
Possession-Time Opportunity (minutes with the ball)
Live
How many minutes per game a player actually holds the ball — published as its own projected number, and the layer underneath every assist projection.Two stages. Each player is carried forward from his own history and charged for how much ball his NEW teammates command. Then every team is rescaled so its total adds up to a projected team budget — because a team cannot decide to hold the ball longer, only who holds it. Team possession time per game varies less across the league than shot attempts do, which is what makes the budget real rather than a modelling convenience.4.4% better than assuming a player holds the ball as much as last season, winning all 20 held-out splits. The budget step costs a little on possession itself and pays for it downstream: it makes players trade ball-time against each other inside a roster instead of everyone drifting the same way.The obvious version — splitting the pool across the rotation by a formula — was built and rejected: it projects possession WORSE than simply carrying it forward, because a player's ball-time is highly persistent and forcing everyone toward a team average throws that away. Rescaling is not the same operation as reallocating, and the distinction is the whole model. A placebo built from a random teammate attribute cannot beat the baseline at all.
Playmaking Opportunity (AST)
Live
Potential assists per 36 minutes — passes that lead to a shot, whether or not it goes in. The quantity assists are actually made of.Last season's rate, adjusted for four things: how much creation his new teammates bring, how much BALL-TIME they take from him, how much of the ball he holds relative to a creator of his volume, and — added 2026-08-05 — his own creation skill, described in the row below. An unchanged roster and an average creator leave the number exactly where it was.The roster terms are worth about 3% against carrying potential assists forward, all 20 splits. The competition that matters is for ball-time, not for creation: once possession crowding is in, the older "how much do your teammates create" term collapses to nothing, because a roster that gains a creator almost always gains a ball-handler.Potential assists were chosen over plain passes because passes are not contested — a big man passing out of the post makes as many as a guard does, while the shot-creating pass is the resource players compete for. Several richer versions were falsified: an allocation that splits creation across the roster (creation is not a fixed team budget the way shots and ball-time are), and front-court touches, drives, rim attempts and pass counts as additional inputs, each of which scored at or below a random-noise placebo.
Minutes Projection
Live
Expected minutes over the next 5 / 10 / 15 games and over the rest of the season, with a range.Recent playing-time form, a discount for back-to-backs, a temporary bump if a same-position teammate is out, and a cap from a realistic rotation size. The teammate-absence bump now fades smoothly to nothing as the horizon lengthens — over a whole season an injured teammate is back long before it ends, so he should not still be inflating a projection.Validated against real held-out outcomes before shipping.Foundational input to every volume-category projection above, rather than a competing approach — there's nothing else it's benchmarked against. One correctness note: until 2026-07-31 the absence bump had no setting for horizons beyond 15 games and silently reused the strongest short-horizon value, so a rest-of-season projection carried a next-week assumption across an entire season.
Team-Crowding Minutes Adjustment
Live
How a roster shares out playing time when its players collectively expect more minutes than a team actually has to give.Every player is first projected on his own history alone, which knows nothing about his teammates. Those are then compared against the roster as a whole: when a team is over-committed, the excess is taken back down the depth chart — starters give up very little, the back of the rotation gives up most. A team that is not over-committed is left completely untouched.On over-committed rosters, 5.5% more accurate than leaving projections alone, and 10.6% more accurate for players who changed teams — the case it exists for. Checked across 2,934 player-seasons and 240 team-seasons: no part of the rotation was made worse, players who stayed put were unaffected, and it held up in 7 of 8 seasons.A simpler alternative — shrinking everyone on a crowded roster by the same percentage — is contradicted by the data: the back of a rotation loses roughly five times as many minutes as the stars do, so an even cut is the wrong shape. Known to under-correct rather than over-correct: about 11% of players with a real role leave the league entirely each year, and real teams absorb part of a squeeze by shedding players rather than by shortening everyone’s minutes, which a model can only see for the players who stay.

3.Ability — what does he do with it?

His conversion: points per scoring chance, rebounds per rebounding chance. A property of the player, largely independent of how much opportunity he is given — so it is computed alongside the steps above rather than after them. The projection is these three multiplied together.

ModelPredictsHow it worksAccuracyCompared against / best performer
Creation Skill (potential assists per minute with the ball)
Live
How well a player turns time with the ball into a shot for someone else — the clearest single number in the assist model.Built from his own games with recent ones weighted more heavily, then pulled toward the league average by how much ball-time stands behind the estimate. A player with two seasons of possession history is trusted more than one with twenty games, and the published band widens accordingly.Draymond Green 2.90 and Nikola Jokic 2.83 at the top; Jalen Brunson 1.76 and Tyrese Maxey 1.89 at the bottom. Pass-first bigs above score-first guards, from a model with no notion of position anywhere in it.This replaced a generalized correction that asked whether a player creates more than his ball-time implies and expected him to fall back. That reading is right on average and wrong for the players who do it every year — it charged Jokic a penalty in all nine seasons on record while his assists climbed. Creation per possession is not a deviation to be corrected; it is a skill that persists, and measuring it directly is what fixed the case. Five other attempts at a better correction factor all failed, and are documented in the repository so they are not retried.
Cold-Start 9-Cat Projection
Live
PTS, REB, AST, BLK, TOV, FG%, FT% and FGA for players with zero games logged this season — rookies, offseason team changes, long injury layoffs.Blends the player's own last season with a 3-year career baseline, using the same empirical-Bayes shrinkage formula the in-season model uses. The more of last season they actually played, the less the number pulls toward the career baseline.Beats a "just repeat last season" baseline on 6 of 7 categories, tested on three full seasons held out from fitting, restricted to players averaging 15+ minutes. Scoring was rebuilt on 2026-08-04 as (shooting efficiency x projected shots) + (free-throw percentage x projected trips), replacing a single blended points-per-chance number — free throws are worth a point each, not the 0.44 that a possession-counting constant had them at.Replaced an earlier version that hand-picked separate blend weights for every category and horizon (16 combinations fit by grid search). The new version needs none of that tuning and matches or beats it on every category.
In-Season 9-Cat Projection
Live (production)
The same 9 categories, once a player has current-season games on record.A 10-game recency-weighted average of each stat, shrunk back toward the player's 3-year baseline by an amount that depends on how much recent playing time actually backs up the new number.Matches the production baseline overall. Testing found the single 10-game recency window applied to every category is measurably worse than a category-specific one.A corrected re-test (an earlier pass had a units bug that reversed the result for 5 of 7 categories) found each category wants its own recency half-life — from 15 games for assists to 75 for steals — on 7 of 9 categories; FG% and FT% genuinely want no recency decay at all. That finding, plus two further validated additions, now runs live in parallel as three experimental 'dev' models below rather than replacing this page directly.
Opportunity Blend (cold-start baseline)
Live (production)
N/A directly — a fix to an input every cold-start projection above depends on: how many shots, touches, or rebounding chances a player is expected to get before he's played a game this season.The cold-start opportunity rate was a pure, unshrunk copy of last season's number, confirmed directly in the underlying code — only shooting/finishing efficiency got blended toward a 3-year baseline, never the raw opportunity itself. This blends the opportunity side the same way, using the same 3-year baseline already computed elsewhere in the pipeline.Beats pure last-season carryforward on 6 of 7 categories at the opportunity-rate level, checked on three seasons held out from fitting. A second, stricter test then asked whether a better ingredient actually produces a better projection — because the shipped number multiplies opportunity by minutes and by finishing efficiency, and a gain in one factor can wash out. It survives, but shrinks a lot: 4 of 4 categories that ship a single projected number improved, at every horizon, by an average of 0.33% rather than the ~5% seen on the rate alone. Notably its two biggest rate-level wins were steals and made 3s — neither of which publishes a single projected number, so that gain never reaches a reader.Directly addresses why the full-season projection used to look like 'just last year's number' for most categories — the single largest fix in that direction this round. A follow-up asking whether players who changed teams over the offseason should trust last season even less did not improve on using one blend weight for everyone — see the tested-and-rejected row.

Variants — the same model under different settings

Not separate models. Each is the pipeline above with four switches set differently: which recency window feeds the rate step, which teammate absences count, whether an age curve applies, and whether schedule adjustments apply.

ModelPredictsHow it worksAccuracyCompared against / best performer
Event-Aware Next-N-Games Projection (dev)
Live — experimental
The next 5 / 10 / 15 games, meant to react to this week's specific situation — who's out, who's next on the schedule, whether the player himself was just traded.The category-specific recency window above, plus a teammate-absence adjustment: when a player's historically identified 'usage partner' is confirmed out, their projection shifts by that pair's fitted per-category delta, reverting immediately (no fade) the moment the partner is back. Also discounts games from before a player's own most recent mid-season trade more heavily than normal recency alone would — detected directly from team changes in the game log, no schedule data needed. An opponent-strength and back-to-back/rest adjustment is coded in the same model but currently inert — both are only knowable from a real forward schedule, and this dataset has no home/away or future-schedule data populated yet.Teammate-absence: a naive, unfiltered version helped only 2 of 6 categories; requiring at least 8 shared 'teammate out' games to trust a pair flipped it to 6 of 6. Trade discount: beat the plain recency baseline on points, rebounds, made 3s and turnovers, both overall and specifically among players who'd just been traded (assists, steals, blocks showed no benefit). Opponent-strength and back-to-back: applying them as a per-game adjustment to a specific future matchup (not smoothed into history) beat the plain recency baseline on 5 of 7 and 4 of 7 categories respectively — all checked on three full seasons held out from fitting.Smoothing opponent strength or rest status into a player's historical average (rather than applying it to a specific upcoming game) was tried first and came back null or worse — see the tested-and-rejected row below.
Event-Unaware Rest-of-Season Projection (dev)
Retired — merged into production
A read for the rest of the current season that deliberately ignores this week's news — no teammate-injury bump, no opponent adjustment.Identical category-specific recency window as the event-aware model above, with the teammate-absence and schedule adjustments switched off entirely. Early in a season, before enough current games exist, falls back to the same improved cold-start blend described in the Opportunity Blend row below.Same underlying recency-window and opportunity-blend validation as the other two dev models; the only difference is which event-driven adjustments are applied on top.Retired on 2026-07-31. Its one real difference from the production model was the opportunity blend below, which has now been promoted into production — after which the two produced identical numbers across all 18,112 projection rows. Rest-of-season is no longer a separate model at all: it is the production model run to the end of the season, i.e. next-N-games where N is the team's remaining games.
Event-Unaware Full-Season Projection (dev)
Live — experimental
A preseason-style, full-season read that stays fixed all season rather than updating game-to-game — built from prior-season and career data, not the season in progress.Reuses the existing cold-start blend — now including the opportunity-side fix below — for every player, unconditionally, even once real in-season games exist. Adds a smooth age/development curve to points, rebounds, assists, made 3s and turnovers, the categories where age turned out to predict real season-to-season rate changes, plus one narrow exception to its own 'no current events' rule: the teammate-absence boost from the next-N-games model still applies here, but only when that teammate is confirmed out for the rest of the season, not an ordinary short-term absence that would otherwise revert.The age curve beats 'assume next season looks like last season' on all 5 categories tested (points improved most). A follow-up found a smooth curve fits better than the original discrete age brackets for 4 of the 5 — solving for where the points curve crosses from growth to decline lands at age ~25, matching an independently-fit alternative model almost exactly. Steals, blocks, FG% and FT% showed no reliable age relationship and were left unadjusted. The season-ending exception reuses the already-validated teammate-absence numbers unchanged; historical injury-status data doesn't go back far enough to run a fresh test of the exception itself, so it ships on that existing validation plus a direct sanity check against a real current case.The only model here built from age at all — the games-played projection above checked age against durability (games missed) and found ~zero correlation; this checks age against per-minute production instead, where a real signal exists for several categories.

Built and evaluated, not shipped

Tested against a real baseline and either rejected or left switched off. Kept visible so they are not rebuilt from scratch.

ModelPredictsHow it worksAccuracyCompared against / best performer
Schedule-Aware Adjustment (opponent strength + back-to-back)
Validated, coded, blocked on data
A shift to a specific upcoming game's projection based on who it's against and how much rest the team has.Each team's per-category 'allowed rate' relative to league average, and whether a given game is on zero days' rest, applied to that specific future game rather than blended into a player's history.Opponent strength beat the baseline on rebounds, assists, steals, made 3s and turnovers (5 of 7); back-to-back beat it on steals, blocks, made 3s and turnovers (4 of 7) — both checked on three seasons held out from fitting.Coded directly into the event-aware next-N-games model above, but inert: applying it live needs a real forward schedule (which team plays which, and when), and this dataset's home/away and future-schedule fields are unpopulated for every row, not just the season ahead. Activates automatically once that data exists.
Tested, not adopted: continuous ratio corrections
Tested — no improvement
N/A — a family of correction ideas checked and rejected, kept here so they are not re-tried unknowingly.Decaying by calendar days instead of games-ago; smoothing a player's history by the strength of opponents actually faced; correcting for teammate-pressure/opportunity ratios; down-weighting blowout games in a player's recency window; using correlated movement across category pairs (e.g. FG% and FT% both improving together) to trust one category's trend more; a full lineup-adjusted (RAPM-style) rebounding model built from real play-by-play and 5-man lineup data; a generalized version of the roster-change idea below scoring every player's surrounding rebounding competition, not just players who personally changed teams; and splitting the opportunity-blend weight above by whether a player changed teams over the offseason.All came back null or reversed on three seasons held out from fitting. Blowout games showed a real, large raw stat drop (10-15%) but it's almost entirely a minutes effect the separate minutes model already handles, not a per-minute rate distortion. The lineup-adjusted rebounding model, properly built and weighted by real shared court time, still didn't beat the existing recency-based projection — a player's own recent output already reflects who he's playing with, leaving little residual to explain. The roster-competition and team-change-blend-split ideas both came back with essentially no relationship to real outcomes.The pattern that emerged: adjustments tied to a specific, forward-knowable event (a confirmed teammate injury, a known upcoming opponent or rest day, a player's own trade) validate; inferred lineup/context signals and smoothing information into a player's historical average do not. The schedule-aware, teammate-absence, and opportunity-blend rows above are the versions that worked. One caveat: the original roster-change rebounding finding below predates this stricter methodology and could not be reproduced by the broader rebuild — see its own row.
Roster-Change Rebounding Adjustment
Validated, not shipped
An adjustment to a player's rebounding projection specifically when they change teams.Estimates how much rebounding competition a player will face from their new, returning teammates, using each player's role profile and rebounding rate — computed before either side has played a game together.A real, moderate relationship with actual rebounding-rate changes (r ≈ -0.23), checked against 778 real team changes across 9 seasons.The same approach was tested for assists, points, turnovers, blocks, and steals; rebounding was the only category where it held up. Flagged for reduced confidence: a later, more careful rebuild generalizing this to every player (not just team-changers) could not reproduce a meaningful relationship — see the tested-and-rejected row above. The original methodology could not be located to reconcile the two results.

Dormant

Superseded work, retained for reference. Nothing here feeds a live projection.

ModelPredictsHow it worksAccuracyCompared against / best performer
Legacy DARKO-style Value Rating (EPM)
Dormant
A single overall value rating (offense / defense / total), plus an early attempt at per-category predictions. Previously updated nightly.Meant to combine a box-score-based skill estimate with real 5-man lineup on/off-court data.Audited against real outcomes: its per-category predictions were worse than "just use last season" on 20 of 21 tests, and it occasionally produced impossible values, including a negative shooting percentage.Worse than the current 9-cat system on every category tested. No longer maintained and not used by anything live.
Rebuilt Value Rating (research)
Research prototype
A single overall value rating (offense / defense / total) — not yet broken into the 9 individual categories.Fixes the legacy version's broken combination step: a player's box-score profile sets a starting estimate of their value, which real lineup data is then allowed to shift, rather than being discarded.Outperformed both the legacy rating and a version with no starting estimate at all, checked against real team performance in two seasons never used while building it.Best of the three overall-rating approaches tested so far. Still produces one overall number rather than the 9 separate category projections the main system provides — not directly comparable to it yet.

See Projection Model for what has been tested and rejected, what is known broken, and what is still untested. See Methods Explained for the full walkthrough of how the live 9-Cat system turns a box score into a projection. This page is a standing reference and will be updated as models move between these categories.