The Lab

The numbers, with their work showing.

This is the clubhouse's model room — and it opens with proof, not promises. The first working tool watches an NFL game as it unfolds — the score, the clock, the down, the field position — and estimates each team's chance to win, play by play. It learned from real play-by-play (2019–2023), then sat a test it couldn't study for: the full 2025 season, which it had never seen. Its grades from that test are published right below, in plain English, with the numbers as the evidence. Move the levers and the number moves with you. A model, not a certainty — the label is part of the tool.

The NFL win-chance model
Loading…
Reading the model card.
Ask Luka to explain →
The honesty test — Brier score
Loading…
The test grades load from the backtest output.
Ask Luka to explain →
NBA — where it stands
Loading…
Only what the free, license-clean check actually produced is shown.
Ask Luka to explain →

No live in-game feed is wired yet — plain version: you set the game situation, and the trained model does the math in your browser, right on this page. Nothing is sent anywhere and nothing is faked. The NBA section below shows the starting foundation and names the one missing piece out loud.

NFL What-If Toolbar

See the calibration ↓

Set the game situation — quarter, clock, score, who has the ball, down, distance, field position, timeouts — and the model recalculates the home team's chance to win, instantly. (The model is a logistic regression: a formula that weighs each of those facts and turns the total into a percentage. Luka can unpack that over at the Ask Luka button.) Every control below is a fact the model was actually trained on; nothing decorative, nothing faked.

Thinking about coaching? The Coach's Corner's decision exams are graded by this model.

Game state

Possession
Timeouts left

Ball position is read from the possessing team's own goal line: the 25 means the offense is 75 yards from scoring. Goal-to-go states cap the yards to go at the yards remaining, the way a real play sheet reads. The toolbar covers regulation states; overtime was a flagged feature in training, not a separate toolbar mode in this starter.

Model output — home team
—
Loading the trained model…
The state you set will be restated here in plain words.

Model version, training window, and test window load from the model card.

A model, not a certainty. A 70% state still loses three times in ten over the long run — the calibration table below is where this model proves how often its numbers meant what they said on games it never trained on.

Calibration — the honesty test, in the open

Every number rendered from the test output — nothing hand-typed

How the test worked, in plain English: the model learned from the 2019–2023 seasons, then we graded it on 2025 — a season it had never seen. (That's what "held-out" means, and it's the only honest way to grade: no studying the exam before you take it.) "Calibration" asks one simple question of the grades: when the model said 70%, did the home team actually win about 70% of the time? The score cards and the table below are that test, row for row — with the public benchmark (nflfastR's own win-probability column) graded on the same plays right beside ours, so our number never grades itself alone.

Loading the test metrics…

Ask Luka to explain these scores →

The reliability table — our model vs the public benchmark (nflfastR)

What the model saidPlaysModel's average callWhat really happenedCall vs realityBenchmark's average callBenchmark reality
Loading the rows…

How to read a row: each row groups every play where the model gave the home team roughly the same chance (the 60–70% row, say). The amber bar is what actually happened; the white tick is what the model predicted on average. Tick landing at the end of the bar means the number told the truth. The benchmark columns are nflfastR's own win probability — its wp column — on the same test plays.

Ask Luka to walk me through this table →

Model card — NFL win probability

Data

What it trained on

Loading provenance…

Method

How it works, and what it is not

Loading method…

The Lab Library — the methods shelf

The library explains · the tools compute

Every number in the Lab stands on a method, and every method is on this shelf — in plain English, with a worked example and its source named. When Luka uses one of these terms in the clubhouse, this is the page it comes from. The shelf has three parts: the model card written the way a person talks, the odds canon (the three pieces of price math every member should own), and the glossary.

Ask Luka to teach from the shelf →

The model card, in plain English

The What-If Toolbar's engine, written out the way the Lab would explain it across the bar. The live data card — provenance and method rendered from the model file itself — is further up this page; its grades render from the test output at Calibration. This is the same card, in words.

What it is

A formula that weighs 20 facts

The model is a logistic regression: it takes 20 facts about a game state — the score, the clock, down and distance, field position, who has the ball, timeouts left, and the spread the market set before kickoff — weighs each one, and turns the total into the home team's chance to win. It learned the weights from nflverse play-by-play, 2019–2023: 204,233 scrimmage plays from 1,385 games. Then it sat two tests it couldn't study for — the full 2024 and 2025 seasons, which it had never seen. The final test (2025: 40,610 plays, 284 games, the season's one tie excluded) is the one that counts.

Its grades on that test, against nflfastR's own win-probability column graded on the same plays: Brier score 0.1610 vs 0.1719 · log loss 0.4814 vs 0.5066 · accuracy 76.0% vs 73.0% · ROC-AUC 0.8446 vs 0.8223. On the 2024 test: Brier 0.1394 vs 0.1570. It beat the public benchmark on every metric in both held-out seasons — and its weakest bins are published in the open, in the limits card beside this one.

The bug we killed

Version 1.0.0 was too good to be true — so we threw it out

The first version of this model read the dataset's score columns as the current score. Those columns quietly hold each game's final score on every row — so the model was, in effect, being told the ending while it "predicted" the game. It scored a Brier of 0.0004 and 99.96% accuracy: a perfect grade that could only mean the test was rigged. We caught it on a sanity check, discarded the version before anything shipped, and rebuilt the current score from the at-the-play columns instead. The training script now asserts that check on every run — on the shipped model, the current margin equals the final margin on 14.1% of plays (only once scoring stops changing), never 100%.

Publishing the failure is part of the method. A Lab that hides its leaks will eventually hide its grades.

The honest limits — printed on the card, not under it

The low end runs hot. In the 2025 test, states the model priced at 0–10% actually won 8.0% of the time (it said 3.9% on average), and the 10–20% bin landed at 21.1% against a 15.0% call. The model is over-confident about nearly-dead teams — the autopsies below include games that lived in exactly that bin.

Accuracy flatters; calibration is the honest read. Every scrimmage play is a row, and late plays in decided games are easy calls — the reliability table at Calibration is the grade to trust.

It prices states, not games to come. The closing spread is baked into every state as pregame context, so this is an in-game pricing model — not a pregame pick engine, and Luka never borrows its percentages for a pregame take. Overtime is a flagged feature, not a separate model, and rule changes across 2019–2025 are not modeled.

The data has an owner-shaped caveat. nflverse is an open community dataset built on league play-by-play — the right foundation for this house's editorial and educational use, carried here with its provenance named rather than laundered into "our data."

The odds canon — three pieces of price math

The library explains; the tools compute. Each card below shows the math in full — then hands you the bettor's toolbox on the Rail, which runs the same arithmetic on any price you type in.

Canon 1

Break-even: the −110 tax

At −110 you risk 110 to win 100, so the price itself implies a win rate of 110 ÷ (110 + 100) = 52.38%. That is the break-even line: win fewer than 52.38% of even bets at −110 and you lose money while picking more winners than losers. A 51% picker is a good picker and a losing bettor at that price — the gap between those two sentences is the whole lesson.

Run it in the toolbox →

Canon 2

Vig removal: find the fair price

Price both sides of a −110/−110 market and the implied percentages sum to 52.38% + 52.38% = 104.76%. The 4.76% over 100 is the vig — the book's margin, built into the price rather than charged at the door. Strip it out (divide each side by the 104.76% total) and the fair, no-margin prices are 50/50 — −100 and −100. Before you judge a line, judge what the vig is hiding inside it.

Strip a price in the toolbox →

Canon 3

Closing-line value: process, graded

If you bet a side at a better price than the price it closes at, you beat the close. From the clubhouse's own closing-line archive (opened October 20, 2026): Detroit's price against Green Bay moved from −167 (62.5% implied) to −172 (63.2% implied) between two snapshots on the archive's first day — anyone holding the −167 owned the better number before a snap was played. The house rule, both halves every time: beating the close over a season is evidence your homework finds numbers before the market finishes pricing them; it is not proof of profit — the vig and plain luck still get their vote.

See the closing-line archive →

The glossary — every term, with a number attached

Win probability

The model's one number for a game state: out of 100 past games that reached exactly this state, about how many the home team went on to win.

Worked example — Giants at Cowboys, 2025 archive: with 33 seconds left the model had Dallas at 90.1%. One 48-yard touchdown later: 25.7%. Same model, same game, one play apart — the full story is in the first autopsy below.

EPA — expected points added

Every play starts with an expected value — what a team usually scores from that down, distance, and field position — and EPA is what the play did to that value, in points. The Lab's plain name for it is points per play.

Worked example — San Francisco's offense averaged +0.209 points per play through Week 6 of 2026 (the Lab's numbers store): across 100 plays, about +21 points of value over an average offense. The full table is at the football numbers.

Brier score

The honesty grade for a probability. Score every call by the squared gap between what the model said and what happened (1 for a home win, 0 for a loss), then average. Lower is better; a permanent coin-flip call of 50% scores 0.25.

Worked example — one play: the model says 65% and the team loses → (0.65 − 0)² = 0.42 added to the pile; the team wins → (0.65 − 1)² = 0.12. Averaged over the 40,610 plays of the 2025 test: 0.1610 for our model, 0.1719 for the public benchmark.

Calibration

Whether the numbers meant what they said: group every call the model made at about the same level, and check whether reality landed at that level.

Worked example — the 2025 test's 30–40% row: 3,840 plays, the model's average call 35.0%, the home teams actually won 34.9% of them. That row is what a calibrated model looks like; the 0–10% row (said 3.9%, happened 8.0%) is the published flaw.

Closing line

The last price on a game before it starts — the market's final answer, after every injury report, weather update, and dollar has had its say. It is the price every earlier price gets graded against.

Worked example — the clubhouse archive's first day (Oct 20, 2026): Detroit moved from −167 to −172 against Green Bay between snapshots. The archive keeps every mark, is never backfilled, and grades the Rail's lines against the close on the Closing Lines page.

Hold / vig

The bookmaker's margin, built into the prices rather than charged at the door. It is why both sides of a game can be priced as if they're more likely than possible.

Worked example — a −110/−110 market implies 104.76% of probability. The 4.76% over 100 is the hold: on a perfectly balanced book, that's the cut that comes out before anyone gets paid. The full worked removal is Canon 2, above.

Sample size

How much evidence a number is standing on. The same stat can be a fact about a season or a rumor about a week — the count underneath it is what tells you which.

Worked example — San Francisco's +0.209 points per play rests on 337 plays through Week 6. At about 56 plays a game, one wild Sunday is a sixth of the whole evidence base — which is why the numbers table stamps its week, and why the last-4-weeks window exists beside the season line.

Sources, named and dated: the model card (NFL win probability v1.1.0, trained October 20, 2026) for the model, Brier, and calibration numbers; the Lab's numbers store (nflverse play-by-play, through Week 6 of 2026) for the EPA and sample-size examples; the clubhouse closing-line archive (opened October 20, 2026) for the closing-line example. The break-even and vig figures are arithmetic, shown in full in the canon cards.

Worked game autopsies — the model, game by game

Six games · picked by rule, not by taste

An autopsy walks one real game through the model's own prices, play by play, and ends with what the model got right and wrong — in that order of honesty. The six games were picked mechanically from all 376 games in the Gamecast stores (the 284-game 2025 archive and the 92 in-season 2026 games): the three wildest rides — the games where the model's win probability changed hands the most in total, adding up every play-to-play move — and the three closest finishes, games decided by exactly one point, ranked by that same total swing, skipping any game already picked. The turning points inside each autopsy are mechanical too: the five largest single-play price moves, no two within four priced plays of each other.

Every play, score, and price below is read from the Gamecast store files, and an audit script re-verifies each citation against those files before this page ships — a claim that can't be verified doesn't get written. Prices are the home team's win chance from the Lab model (v1.1.0): a turning point's "before" is the model's price of the state before the play ran; its "after" is the price at the next priced play.

Loading the autopsies…

Build Your Own Line — the starter strip

Pregame · your numbers, your assumptions House layer — open in preview

Pick two teams and the strip starts from the Lab's own power ratings — one number per team: how many points better or worse than an average team on a neutral field, worked out from real game margins across the 2019–2023 seasons by the method spelled out under the table below. Set the home-field value and a rest edge, and your line builds in the open. This is modeling education: the output is your number from your settings, never a betting recommendation.

Your settings

Rest is a display-only adjustment in this starter: a lever you set and see, labeled as your assumption. It is not a fitted rest effect and no rest claim is made for it — the honest version of the lever until a rest model is trained and backtested of its own.

Your line
—
Loading the ratings table…
The arithmetic will show here, lever by lever.

No market column in this starter — on purpose. A market reference belongs beside a specific game whose line is present in sourced data. This strip works from ratings, not a named game, so no market number is shown rather than an invented one being placed next to yours.

Power ratings — the full table

How to read the numbers: +7 means about a touchdown better than an average team on a neutral field; −6 means about a touchdown worse. The difference between two teams' ratings, plus home field, is a spread — that is the whole machine. The method line under the table is the fine print (an "SRS-style" fit — the standard way tables like this have been built for decades); ask Luka and he'll translate any of it.

Loading the ratings method…

#TeamRating (pts)
Loading ratings…

The football numbers — teams and players, in plain words

The layer under the picks

Standings tell you who won. These numbers tell you how well a team is actually playing — because a 4–2 team that got marched on all game and a 4–2 team that marched are not the same 4–2, and your pick card deserves to know the difference. Every number below is computed in the house from the real play-by-play, derived twice by two separate passes before it publishes, and stamped with its source and the week it runs through. The plain name is the headline; the technical name rides in small print, the way it should.

Points per play
Every snap either moves a team closer to scoring or pushes it back. This is the average value of one play — the single best one-number read on an offense. (Technical name: EPA per play.)
Points allowed per play
The same read pointed the other way: what an average play gains against this defense. Negative is good here — it means offenses go backwards. (Defensive EPA per play.)
Steady plays
How often a play actually helps — moves the team closer to scoring. High and steady beats lucky and spectacular over a season. (Success rate.)
Big plays
How often a play pops for 20 yards or more. The boom in a boom-or-bust offense — exciting, and the first thing a good defense takes away. (Explosive-play rate.)

Team numbers — NFL

Passing value and running value are the points-per-play read split by play type. Pace is offensive plays run per game — more plays, more chances, more points in the air for everybody. Click a column heading to sort by it.

Team Points per play Pts allowed / play Steady plays Big plays Passing value Running value Plays / game
Loading the numbers…

The method and the stamp load with the numbers — nothing prints without them.

Ask Luka who's playing best per play →

Player numbers — NFL

Real players, real lines, straight from the source's weekly stat sheets — every season total cross-checked against the source's own season table before it prints here.

#PlayerTeamPosTotalThe lineGames
Loading the player numbers…

The stamp loads with the boards.

Ask Luka who's leading the league →
On your pick card

A leaky defense meets a big-play offense

When the team that allows the most value per play meets an offense near the top in big plays, expect points — the kind of game where the favorite's defense can't be trusted to close the door. Read the two columns side by side before you trust a record.

On your pick card

The record lies; the per-play doesn't

A team can be 2–4 and top-eight in points per play — close losses against a brutal schedule — or 5–1 while getting outplayed weekly. The standings say who won. This table says who's playing well, which is what next week cares about.

On your pick card

Last 4 weeks is the "right now" read

Flip the window. A season line remembers September; the last-4-weeks line is who a team is today — after the injuries, the benchings, and the fixes. When the two windows disagree, believe the recent one and ask Luka why they split.

NBA — where it stands, in plain words

Loading the NBA foundation…

Luka works in here

What-If

Set the state, he'll walk it

Luka can restate any toolbar state in plain words, explain which lever moves the number most, and quote the model's calibration — and when chat can't run the model itself, he says so and points at the toolbar readout instead of inventing a percentage.

Ask Luka how it works →

Build Your Own Line

Co-build in words

Give Luka two teams and your levers and he restates them, shows the arithmetic line by line, and narrates which lever is doing the work — his closing line never moves: your numbers, your assumptions, not betting advice.

Start a co-build →

The Take

What the Lab changes — and what it doesn't

The Lab's first NFL model prices in-game states; it is not a pregame pick engine, and Luka's pick'em picks still run on the labeled knowledge rule. Where a Lab model genuinely covers a question, its number carries the model card with it. Where none does, the take runs on tiers — never an invented percentage.

See Luka in pick'em →