A one-page look under the hood. I'm keeping the exact formulas and weights to myself, but this is an honest account of how it works, including where it falls short.
The premise
Spin a wheel of the 60 Super Bowl-winning teams (1966–present). Draft one player from whichever champion you land on. Fill your roster, then run it through the actual four-round playoff bracket against real historical opponents. About 1 in 10 well-built rosters wins it all. Losing is the point, and losing to a specific team ("eliminated by the '85 Bears") is the story you share.
Under that simple loop is my attempt at a genuinely hard question: how do you put a 1972 fullback and a 2023 edge rusher on the same 0–99 scale, fairly? I think everyone who builds one of these models is convinced theirs is right. I'm not convinced mine is, but I tried.
Layer 1: player ratings, normalized across eras
The core problem with all-time comparisons is that the game changed. A 3,000-yard passing season meant something very different in 1978 than in 2013. So every stat is z-scored against position peers within its own era before anything gets combined, and raw volume never crosses era boundaries. On top of that base:
- Rate stats, weighted season + playoff: per-game production, not career volume, so a short brilliant peak isn't buried by longevity.
- A clutch adjustment: a player's playoff production relative to their own regular-season baseline, minus the league-average January drop-off for that era and position. It rewards players who actually rose when it mattered, not just anyone who happened to play in January. The first time I ran it, it spit out Playoff Lenny, Vinatieri, and Montana on its own, which is when I started to trust it more than my own opinions.
- An awards modifier: MVP, DPOY, Super Bowl MVP, and the like, as a capped bump.
- A pre-1999 fallback: box-score data doesn't exist that far back, so those players are rated from career honors (All-Pro and Pro Bowl selections) on a prime-weighted curve, and clearly flagged as estimated.
The result is a 0–99 scale where the "99 club" comes out looking a lot like an inner-circle Hall of Fame, and no single decade dominates. That was the sanity check I cared about most.
Layer 2: roster fit
A team is more than the sum of its ratings. The model scores archetype synergies (a deep-ball QB paired with a deep threat; a power back behind a mauling line) and penalties (a bomber behind a weak line; blitzers with no press corner to hold up). In the 23-man mode you also name a captain for a leadership bonus built from rings, documented captaincy, and command of the huddle. Every rule is transparent. It fires by name as you draft, so fit is a lever you pull rather than a black box.
Layer 3: the gauntlet
Opponents aren't invented. They're the actual teams that played each playoff round in history, drawn round-by-round, each carrying a strength rating built from regular-season point differential blended with the Vegas line (the betting market's opinion, which has ~100% coverage since 1999). Each game is a logistic function of the strength gap, plus home field, an "any given Sunday" noise term, and a rising difficulty curve. Identical rosters get different runs, which is the replayability.
The tuning took forever, and it still feels a little off
This part ate more evenings than I want to admit. Every tunable value lives in a single config file, and a deterministic bulk-simulation harness drafts thousands of rosters across several strategies and runs about 120,000 gauntlets, scoring the outcomes against explicit balance targets:
- championship rate for a typical roster lands near 10%;
- a top-decile roster wins roughly 45% of the time;
- no single exit round absorbs the field;
- stacking defense is not a degenerate winning strategy (an early guardrail the harness actually caught and forced a fix for);
- the fit system is load-bearing: it flips a measurable share of close games, or it isn't pulling its weight.
Because the simulation is fully deterministic, every result is reproducible, and re-tuning is a measured experiment rather than vibes. The harness has overruled my instincts more than once, which is humbling coming from code I wrote myself.
Where it's imperfect
I'll be straight about the model's weak spots:
- Box scores are kinder to quarterbacks and skill positions than to linemen and defensive backs, so those ratings lean more on snap counts, honors, and judgment.
- Pre-1999 players are rated from career honors, not stats (the data simply doesn't exist), and they're flagged as estimated in the game.
- Any single number for a 1972 fullback involves a judgment call somewhere. The harness keeps the ratings consistent and the game balanced. It can't make them true.
If you can poke a hole in it, I genuinely want to hear about it. And if your guy's rating is too low, I understand, and I will be hiding behind the z-scores.
Data & stack
Player and game data from nflverse (1966–2025). Build pipeline in Python; the game is a dependency-free static site with a shared, pure-JavaScript engine (the exact same rating/simulation code powers both the browser and the tuning harness, so there's no drift between what's tested and what ships).
Questions, holes to poke, or partnership ideas: @FBGauntlet. I read everything.