Three seasons of games, four of tryouts, and a mess of names to reconcile before any of it means anything.
NSBA is a science-bowl league run like the NBA. Every player takes a combine β a standardized 24-question tryout β then fourteen captains build rosters through a snake draft and play a season of head-to-head matches. Two scoring systems live side by side and are never mixed. Game rounds use standard Science Bowl scoring: a correct toss-up is +4, a wrong interrupt (a "neg") is β4, and a converted team bonus is +10. The combine is pyramidal β buzz earlier for more credit (+4 / +3 / +2), with β1 for a wrong multiple-choice guess β which makes it gameable: because only wrong MC buzzes are penalized, late guessing ("biking") is positive-EV. So the combine is used only as a predictor, never as a measure of value.
The corpus is small and we say so up front. Game scoresheets span three seasons (2022, 2023, 2025), reconciled to a clean set of 180 games β the games that both balance and aren't empty templates:
$$\text{clean} = \{\, g : \texttt{reconciles}(g) \;\wedge\; \neg(\texttt{score}_a{=}0 \wedge \texttt{score}_b{=}0)\,\}$$That yields 41 team-seasons and 207 player-seasons over 181 distinct people, plus 216 draft picks across three drafts. Combine data covers four seasons including the current one β whose games hadn't been played when the models were built. The parser is faithful: the combine reconstructs with zero mismatches, and per-player points reconcile exactly against the buzz-attributed totals.
The single most load-bearing discipline in the whole project: the pyramidal, gameable combine and the standard-scored game are never folded into the same statistic. The two even use different code vocabularies (b/ch/cs/ess/m/p in games, bio/chem/β¦ in the combine), which forces an explicit crosswalk on every join and makes accidental mixing hard. The one time the guardrail slipped β an early finding that "CS points are worth 3.5Γ" had quietly fed team bonus points into a per-player regression β an adversarial re-audit caught it and the ratio collapsed to β1.8Γ (and lost significance). More on that in Β§10.
A player appears as a Discord handle in one place, an in-game nickname in another, a real name in the combine. Every raw string is mapped to a canonical_id by a union-find over five bridge rules (shared Discord tag, exact real name, a nsba1 nicknameβname "Rosetta" sheet, and two team-scoped fuzzy matches). Matches are never forced: 65 ambiguous identities are kept raw, and a bare first name appearing on two different teams is treated as two humans, not merged. The draftβgame roster bridge is scored by Jaccard overlap of canonical rosters,
and its per-season quality is wildly uneven β median 0.11 in nsba1 (nicknames vs real names: effectively unlinkable), 1.00 in nsba2, 0.50 in nsba3. This is why nsba1 is essentially games-only and nsba2 carries most of the draft-outcome story.
The base currency is points per toss-up faced β not per game, because bonuses are team-answered and can't be attributed to an individual:
$$\mathrm{PPTF} = \frac{\texttt{toss\_points}}{\texttt{tossups\_faced}} = \frac{4c - 4g}{n},$$where c = correct buzzes, g = negs, n = toss-ups faced. How much of the spread in PPTF is talent versus sampling noise? A method-of-moments variance decomposition splits observed variance into between-player (true) and within-player (sampling) parts; the ratio is the stabilization constant M, and reliability at n trials follows:
$$M = \frac{\overline{\sigma^2_{\text{within}}}}{\sigma^2_{\text{between}}}, \qquad \rho_n = \frac{n}{n+M}, \qquad \widehat{\text{PPTF}} = \frac{n}{n+M}\,\overline{\text{PPTF}} + \frac{M}{n+M}\,\mu.$$PPTF stabilizes at M β 35 faced toss-ups (reliability 0.5, ~1.5 games); at the median sample of ~150 faced, Ο β 0.81 β we keep about 80% of the signal. An independent empirical split-half, corrected by SpearmanβBrown
$$r_{\text{full}} = \frac{2\,r_{\text{half}}}{1 + r_{\text{half}}},$$agrees at 0.82, which is the check that the whole reliability edifice actually holds. Neg rate, by contrast, has M β 23 but a tiny denominator (~12β15 buzzes), so Ο β 0.35 β mostly noise, and shrunk hard toward the league mean.
Before the season, all you have is a cheatable tryout. Here's how much to trust it β spoiler: not much.
Every player takes a 24-question combine (6 categories Γ 4 pyramidal questions, buzz earlier for more credit). The catch: a wrong multiple-choice guess costs only β1 and short-answer buzzes are free, so late guessing β "biking" β is positive-EV, and a weak player can inflate a raw score. So we don't score it arithmetically; we fit a graded-response IRT model, recoding each question to an ordered outcome (wrong-bike < skip < no-credit < +2 < +3 < +4) and estimating each player's latent ability from the pattern, not the point total:
$$P_{ik}(\theta) = \underbrace{\sigma\!\big(a_i(\theta - b_{i,k-1})\big)}_{\text{clear boundary }k-1} - \underbrace{\sigma\!\big(a_i(\theta - b_{i,k})\big)}_{\text{clear boundary }k}.$$Fit by marginal maximum likelihood, read out as a posterior-mean (EAP) ability with its error bar; a re-fit that drops the bikeable tier ("de-biking") corrects the worst gaming. It's a tidy model. But here's the honest part, and the reason this section is short: the combine only correlates β0.6 with what players actually do in games β it explains about a third of the variance and no more. For a suspected tanker it's a gamed ceiling; for a reliable returner it's an honest floor; for everyone it's a prior we lean on hardest for rookies with no tape and abandon the moment real games arrive. Which they do β and that's where the interesting modeling actually happens.
Baseball's projection playbook β stabilize, regress, age β ported to a buzzer.
Projecting a player is a four-step "Marcel" spine borrowed from sabermetrics. Weight prior seasons by recency (newest gets weight 5, then 4, 3) and by sample; compute the stabilization constant from variance components; then regress the weighted rate toward the league mean with M β 35 toss-ups of padding. The empirical-Bayes shrinkage is a single line:
$$\hat\theta_{\text{PPTF}} = \frac{n_{\text{eff}}}{n_{\text{eff}}+35}\,\bar x_{\text{obs}} + \frac{35}{n_{\text{eff}}+35}\,\mu_{\text{PPTF}}, \qquad \mu_{\text{PPTF}} = 0.332.$$Per-category projections shrink harder (padding β 5.8, since a subject sees ~β the volume), so a two-buzz "CS specialist" is pulled most of the way back to average β appropriately. Replacement level is the projected rate of the 70th-ranked player (a 14Γ5 league), and VORP = (ΞΈΜ β 0.298) Γ 150. Because the talent pool is thin, replacement sits near average, so VORP cleanly separates the elite but flattens the middle.
A naΓ―ve year-over-year delta shows players improving +0.43 z per edition β but much of that is regression-to-the-mean of a negatively-selected returning cohort. Fitting the change on prior level separates the two effects:
$$\Delta\theta = \beta_0 + \beta_1\,\theta_{\text{prior}},$$where Ξ²1 β β0.43 is mean reversion and Ξ²0 β +0.41 z is the true net development for a returner starting at the mean (95% CI [+0.13, +0.68]). The rule that follows is strict: apply reversion and development once, together β never stack a growth bump on top of shrinkage, or you count the same climb twice.
Two lenses. Win Shares distribute a team's actual wins by scoring share, so they sum exactly to the team total: WSp = point_sharep Γ team_wins. Win-Probability-Added models the final margin as a Normal that collapses onto the running score as toss-ups resolve, and credits each buzz's swing to the player:
$$P_A(\text{win}) = \Phi\!\left(\frac{\text{margin}}{\sigma_{\text{rem}}}\right), \qquad \sigma_{\text{rem}} = \text{RESID\_SD}\sqrt{\tfrac{\text{tossups remaining}}{N}}, \quad \text{RESID\_SD} = 56.$$The residual SD is deliberately un-cocky β a 20-point lead is only ~65% pregame β so early swings aren't inflated; 1.00 WPA β one full win added.
Three orthogonal skill-minus-variance separators keep us honest: points above expectation (actual gets minus what the win-model expected from the player's actual lineup); Pythagorean wins from point differential, win% = PFk/(PFk+PAk) with k = 2.37 pinned (a free fit overfits 4β5 games/team); and the model residual, realized output minus combine prior, both z-scored. When all three agree a player is under- or over-rated, we believe it; when they don't, we don't.
The field drafts the tryout, not the talent. The inefficiency is real; the size of it, less than we first claimed.
Here is the market inefficiency in two numbers. The field drafts almost mechanically off the visible raw combine β the rank correlation between pick order and combine score is 0.67β0.75 every season. But the combine predicts realized value only at Ο β 0.36β0.43. The room over-anchors on a gameable tryout: that gap is real and directional. How much it's actually worth is where I have to walk myself back.
In betting terms the combine is the number everyone anchors on, so the draft prices like a soft book, and fading it β taking the talent the tryout underrates, passing on the biked-up darlings β is directionally the +EV play. But the magnitude an earlier draft of this post bragged about, "~13 toss-points per slot," does not survive a hard look, and the quant we sent this to caught it cleanly. That figure comes from a single clean-linkage season (nsba2) on about nine names. Pooled across the whole corpus the recoverable edge is closer to ~2β3 points a slot; it roughly vanishes in the season that most resembles today; and the one fully-independent test of "the field mis-drafts talent" comes back null β the combine's own link to the pick-slot residual is 0.007 (p = 0.95). So the inefficiency is real in direction, shaky in magnitude, and quite possibly not exploitable once you're honest about the linkage artifacts. It's the closest thing to an edge in the entire project β which mostly tells you how little edge there is.
Joining each pick to its realized win-shares and fitting a curve over the normalized snake slot gives a clean exponential (not linear) decay:
$$\widehat{\text{value}}(\text{frac}) = 0.285 + 2.47\,e^{-6.28\,\text{frac}}.$$Rescaled so pick 1 = 100, the round-openers are worth roughly 100 / 42 / 22 / 15 / 12 / 11 β a steep top and a long flat tail, and the curve is convex (the top pick is worth more than a linear board implies). The real "loser's curse" isn't a lower mean at the top; it's variance: round-1 busts run 15%, round-6 busts 73%. Early picks are insurance as much as talent.
The live draft grade β the one the community bot reports β is a rank delta. A player's value is a balanced z-score of skill and volume, ranked, and compared to where they were drafted:
$$\text{value\_score}_i = \tfrac{1}{2}\big(z(\text{Buzzer Elo}_i) + z(\text{toss\_points}_i)\big), \qquad \text{steal\_score}_i = \text{pick\_rank}_i - \text{value\_rank}_i.$$Positive means drafted later than they've played (a steal); negative means a reach. It runs on a small Β± integer scale (~Β±25) β and is deliberately not the same quantity as the ability-adjusted "value grade" on the draft-value page, which uses IRT/PPTF on a Β±70 scale. Two different yardsticks for the same idea. The season's biggest steals were late-round finds (Uddip K at pick 61, +33); the biggest reaches were early picks who underdelivered.
Two sophisticated adjustments were built and then honestly shelved. Contestation-adjustment β a PlackettβLuce model, P(i wins | field) = eΞΈi / Ξ£ eΞΈj, to strip out the "empty stats" a lone star vacuums on a weak team β reorders the board by almost nothing (Spearman 0.93 with raw PPTF; the confound test is a clean null). Duo synergy β do complementary teammates over-produce? β is a bounded null: zero of eight tests survive multiple-comparison correction. The lesson is that team-building here is additive: draft the best individual value, don't chase fit.
The one structure that held is archetypes. K-means on a fused combine+game per-subject vector finds five soft clusters, and only one β "elite multi-science" (broad and deep, chem/physics core) β reliably wins, carrying ~4Γ the win-shares and essentially all the VORP. Notably, there is no pure-CS archetype: strong CS players ride with the broad elites.
This is the part everyone actually cares about: we posted a line on every game for six weeks. Here's the scoreboard, and it's humbling.
The model's job was to call games. Across the first six weeks β 36 games with a published line β it went 20-16 straight up (55.6%). Sounds fine, until you meet the baseline: always pick the home team went 27-9 (75%). The dumbest possible heuristic beat our log-sum-exp-softmax-Bayesian machine at every horizon. So let's answer the only question a bettor actually cares about, up front and in bold: would you have made money betting this model? No. 20-16 is roughly break-even before the vig, and blind-betting home would have buried it. Its Brier score is 0.250 β identical to shrugging "50/50" every week. Two caveats, cutting both ways: at n=36 that record is statistically indistinguishable from a coin in either direction (55.6% carries a 95% CI of about [39%, 71%]), so we can't prove it's worthless either β and a Brier tie can hide real signal behind bad calibration, which, it turns out, is exactly what's happening here.
| Week | Games | Straight-up | SU % | ATS (home) | Spread MAE | Brier |
|---|---|---|---|---|---|---|
| 1 | 6 | 1β5 | 16.7% | 5/6 | 51.8 | 0.312 |
| 2 | 6 | 4β2 | 66.7% | 4/6 | 34.7 | 0.245 |
| 3 | 6 | 6β0 | 100% | 4/6 | 42.0 | 0.176 |
| 4 | 6 | 3β3 | 50% | 3/6 | 65.3 | 0.264 |
| 5 | 6 | 3β3 | 50% | 5/6 | 41.7 | 0.262 |
| 6 | 6 | 3β3 | 50% | 5/6 | 47.3 | 0.241 |
| Total | 36 | 20β16 | 55.6% | 26/36 | 47.1 | 0.250 |
Under the scoreboard is a clean generative model. Each team's per-subject strength is a log-sum-exp pool over its lineup, the three-way toss-up outcome (A / B / dead) is a softmax, the margin is a sum of independent toss-ups and therefore Normal by the CLT, and the win probability is one normal CDF:
$$P(A\text{ wins toss-up}) = \frac{R_{A,s}}{R_{A,s}+R_{B,s}+e^{c_s}}, \qquad P(A\text{ wins game}) = \Phi\!\left(\frac{\mu_M}{\sigma_M}\right),\;\; R_{T,s}=e^{\beta\,\operatorname{logsumexp}_{p\in T}\theta_{p,s}}.$$It's a nice model. It just runs into a wall: on the historical backtest, combine ability explains only 1-(56.2/57.9)^2 β 6\% of margin variance. A ~150-point game has a ~56-point residual SD β most of the outcome is same-day noise no rating can see.
The ~6% ceiling is the irreducible problem. But there was a very reducible one hiding in the calibration, and it's the sharper lesson. In NSBA the home team bans a category, so home teams won 75% of games β yet the model's mean probability on its own favorite was just 0.553. It barely leaned home. Bucket the predictions and the miss is glaring:
| Model said P(home) | Games | Home actually won | Miss |
|---|---|---|---|
| 0.40 β 0.45 | 7 | 85.7% | +0.44 |
| 0.45 β 0.50 | 11 | 54.5% | +0.07 |
| 0.50 β 0.55 | 9 | 88.9% | +0.38 |
| 0.55 β 0.60 | 6 | 83.3% | +0.25 |
The probabilities are both under-dispersed (they hug 0.5 β the standard deviation of p β 0.5 is a measly 0.072) and mis-centered (too low on the home side). The spread shows the same tell in tradeable form: home covered the model's own number 26/36 = 72%. In plain terms, we were so reliably light on home that fading our own spread and taking home would have hit 72% β a cleaner signal than the moneyline, and proof the miss is a systematic side bias, not variance. Two honest hedges, though: those bucket cells are 6β11 games and non-monotonic (noise texture, not a clean slope), and a home offset fit on these same 36 games would overfit exactly like the Week-3 blunder below β the direction (we under-credit home) is safe, the magnitude isn't. And home's 75% rests on a real mechanism (the category ban is a rules artifact), not just a 27-9 record that on 36 games is itself a wide [59%, 86%]. We were tuning the engine while the wheel was pointed slightly the wrong way β an ordinary, humbling failure.
The arc is worth telling straight, because it's the kind of trap every modeler falls into. Week 1 posted road favorites with full rosters and went 1-5 β the worst week. We fixed the two obvious things: projected lineups (use who actually dressed last time, catch the no-shows) and a dispersion fix, and Week 3 came back 6-0, Brier 0.176 β the peak. Feeling good, we ran an in-sample backtest, saw that a model-only line beat the 70/30 market-futures blend 83% to 50%, and dropped the blend. Then Weeks 4, 5, and 6 all went 3-3 at a coin flip.
The home team wins three of every four games. The only home mechanic is banning one category β call it 14 points. Fourteen points shouldn't do that. So what's really going on?
The instinct to distrust that 75% from Β§5 is correct, and worth working through, because the arithmetic doesn't obviously support it. NSBA is played online β no travel, no crowd β so the entire home-court effect is one rule: the host bans a category, removing roughly one toss-up and its bonus, about 14 points, from the board. On a game whose margin has a standard deviation of ~57 points, a 14-point shift moves the win probability to only
$$\Phi\!\left(\frac{14}{57}\right) \approx 0.60.$$So a face-value 14-point ban predicts a 60% home team β not 75%. Taken at its sticker price the mechanism is nowhere near big enough. Something has to give.
The obvious escape hatch is a scheduling confound β if the better team tended to draw the home slot, "home advantage" would just be team strength in disguise. It isn't. Hosting in this league is a coin flip, and the data agrees: home teams averaged a 51.9% season win rate versus 48.1% for visitors β a 3.8-point sliver β and the home team was actually the stronger side in only 17 of 36 games (47%, itself a coin flip). Hosting is split two-or-three games apiece across all fourteen teams. So whatever edge does show up this season is caused by hosting, not selected by it β which matters once we pin down how big it actually is.
Our first pass measured this season alone: home teams outscored visitors by a mean of +24.8 points, so we spun a tidy story β the ban must be adversarial (you remove the opponent's single best category, an order statistic above the mean), so it's "really worth ~25, not 14." It's a satisfying story. It's also mostly wrong, and the honest fix is the boring one: get more data.
Reach back to the three prior seasons and measure the exact same thing under the same convention β the right-hand team on the scoresheet is the host. Across 168 clean regular-season games, home court is worth nothing:
| Season | Games | Home win % | Home margin |
|---|---|---|---|
| NSBA 1β3 (all) | 168 | 45.8% | β3.8 |
| nsba1 | 66 | 48.5% | +2.7 |
| nsba2 | 61 | 48.4% | β3.2 |
| nsba3 | 41 | 37.8% | β14.9 |
| nsba4 (this season) | 42 | 64.3% | +18.4 |
Historically the host wins under half its games (45.8%, 95% CI [38%, 53%]) and the margin CI straddles zero (β3.8, [β11.8, +4.3]) β no home-court edge, if anything a hair negative. And this season, measured cleanly by the scoresheet's right column rather than the platform's soft home/away label, the edge is +18.4 ([+1.4, +35.4]) at a 64% win rate β real, but nowhere near +25/75%, and only just clearing significance.
This recalibrates Β§5, too. The engine priced home at roughly +14 / 60% β which turns out to be about right. What beat it there ("always pick home," 27-9) was a home side that over-performed its true ~64% in a 36-game sample. The model did still under-lean home, but the gap it missed is a handful of points of win probability, not the 20+ the raw 75% implied.
Pricing the league's play-money prediction market β and a live trader that lives off variance collapse.
The league runs a play-money prediction market, which needs prices. Take the flagship binary β "will player X score more than 32 toss-up points in some single game this season?" Model per-game points as Normal, price the tail, and compound over the season's games under independence:
$$p_{\text{game}} = 1 - \Phi\!\left(\frac{32 - \mu}{\sigma}\right), \qquad p_{\text{season}} = 1 - (1 - p_{\text{game}})^{N}.$$The mean comes from the player's rating (a regression with RΒ² = 0.98, on all of thirteen players β read with suspicion); the variance is Bayes-blended with history or a population model. This gave Sanjay S β 79% and Kian D β 40% to hit the line β and the fat tail matters: a high-variance player gets a bigger over-shot than his mean alone suggests. When bets are placed, size them by fractional Kelly against the market price:
$$f^{*} = \frac{p - \text{price}}{1 - \text{price}}, \qquad \text{stake} = 0.35\cdot\text{bankroll}\cdot f^{*}.$$The platform is a Hanson LMSR automated market maker: prices are a softmax of outstanding shares, and the cost to move them is
$$C(q) = b\,\ln\sum_i e^{q_i/b}, \qquad p_i = \frac{e^{q_i/b}}{\sum_j e^{q_j/b}}.$$Because LMSR is shift-invariant, the bot reconstructs the full share vector from just the observed prices and the liquidity parameter b (qi = b ln pi), then buys until the marginal price hits fair β 0.02 (the average fill beats the marginal, so it's +EV by construction). The edge itself comes from variance collapse: as toss-ups resolve, the live win probability conditions on the running score and the remaining uncertainty shrinks toward zero:
$$p_{\text{live}} = \Phi\!\left(\frac{M_k + \mu_{\text{rem}}}{\sigma_{\text{rem}}}\right), \qquad \sigma_{\text{rem}} = \frac{\text{RESID\_SD}}{\sqrt{N}}\sqrt{N-k} \;\to\; 0.$$The model is essentially "collapse the Normal onto the score" β the ability correction is a near-negligible tie-breaker, since Ξ² = 0.296 means skill barely moves a single toss-up.
When a buzz happens is mostly a fact about the question, not the person β with one important open door.
How early someone buzzes feels like it should measure how good they are. We modeled buzz order as a PlackettβLuce race: each player carries a latent buzz-speed strength, and the probability they beat a field is a softmax,
$$P(i\text{ buzzes first} \mid \text{field } S) = \frac{e^{\theta_i}}{\sum_{k\in S} e^{\theta_k}},$$with dead questions retained through a shared "virtual competitor" term. Fitting this and folding in the actual buzz position (celerity) turns out to add almost nothing: the celerity-weighted rating correlates 0.99 with a pure who-won-the-buzz model, and buys zero held-out predictive lift. Everything the buzzpoints "know" is already implied by who beats whom. A competing "buzz-rank" feature was actively worse β it promotes low-volume fast buzzers and punishes high-volume elites, measuring style, not quality.
The deeper reason is a reliability wall. Split-half reliability of a player's average buzz position is r β 0.08 β about 92% noise β because a player buzzes only ~5 times a season, so their mean is dominated by which questions they happened to face. The very same buzz data, aggregated by question, is reliable at r β 0.58: a packet is reused across ~6 games, so buzz position is a genuine question-difficulty signal. The signal that's real in the data is question hardness, not player speed β which is why buzz timing informs our difficulty priors and stays out of the player ratings.
A specific, falsifiable claim β "a few great buzzes reveal category mastery better than the average" β put to the data.
The argument is intuitive and worth taking seriously: information is disproportionate, so a player's two or three fastest conversions on hard clues should reveal what they truly know better than a season of middling averages. To test it, we need an ability truth that is independent of in-game buzzing β the combine IRT ΞΈ per category β and we ask which family of in-game features predicts it better.
For every (player, subject) cell with at least three correct buzzes, we built two feature families. Mean/volume: get count, get rate, average buzz depth. Peak/extreme: the single fastest buzz, the mean of the top-2 and top-3 fastest, and conversions on the hardest questions. Then a head-to-head, leave-one-out out-of-sample RΒ² at predicting combine ΞΈ. Coverage, stated honestly: 87% of buzzes join to an identity, leaving 81 cells across 43 players β thin, and that thinness is the binding constraint.
| Model (predicting combine ΞΈ) | features | out-of-sample RΒ² |
|---|---|---|
| Mean / volume | 4 | β0.051 |
| Peak / extreme | 7 | β0.116 |
| Select peak (feature-matched) | 3 | β0.034 |
| Both | 11 | β0.162 |
The verdict: we can't tell β and being honest about that is the finding. Every family lands below zero out-of-sample, and that does not mean "peak is worse than mean." It means neither recovers the target, so the β0.12 vs β0.05 gap is a comparison of two noise realizations. At n=81 the experiment is underpowered to the point of being uninformative about the contrast at all. And the one wrinkle actually cuts toward the theory: the single strongest correlate is a peak feature β fastest buzz, r = β0.22, 95% CI [β0.42, 0.00], p=0.046 uncorrected β so if the thin data leans anywhere, it leans for "select buzzes," not against. We didn't refute the idea. We found we don't have the sample to test it.
The mechanism is a one-way analysis of variance on buzz depth, and it's decisive: which question it is explains 76% of the variance in how deep a buzz lands; the player explains only about 10%.
Simulating the season 50,000 times β and letting adversaries try to break every finding.
Playoff odds come from Monte-Carlo. Each remaining game draws a margin from the calibrated engine, seeds are set by the real tiebreak (wins, then total points scored), and the bracket is run tens of thousands of times. Any probability is a sample mean, with a Monte-Carlo standard error small enough to ignore:
$$\hat p = \frac{1}{N}\sum_{k=1}^{N}\mathbb{1}[\text{event}_k], \qquad \text{SE}(\hat p) = \sqrt{\frac{\hat p(1-\hat p)}{N}} \approx 0.002 \;\;(N = 50{,}000).$$The title odds come out flat β the favorite sits near 16%, the field bunched behind β precisely because the ability engine can barely separate teams (recall the ~6% margin variance). The championship is mostly seeding and variance, not a runaway. That flatness is a finding, not a bug.
The technical centerpiece is a joint hierarchical Bayesian model β the kind of thing you'd see in a psychometrics paper, fit here with the No-U-Turn sampler. One latent per-(player, subject) ability vector feeds two likelihoods at once β the games and the combine β with partial pooling across players and seasons and a per-player "bias" term that literally learns how much each person games the tryout:
$$\theta_{p,s} = \text{overall}_p + \text{subject}_s + \tau\,\varepsilon_{p,s}, \quad \text{PPTF}_i \sim \mathcal{N}\!\big(\mu^{\text{game}}_i, \tfrac{\sigma_0^2}{n_i}\big), \quad \text{combine}_j \sim \mathcal{N}\!\big(\mu^{\text{comb}}_j, \sigma_s^2\big).$$It's the right architecture β a player becomes a six-dimensional vector, not a scalar, which correctly re-rates specialists a flat PPTF buries, and it hands combine-only rookies honestly wider intervals (~1.7Γ). It converges cleanly (zero divergences). And here is the discipline that matters most: out-of-fold, it does not beat raw combine. Drop a season's games, predict from combine alone, and the joint model lands at LOSO rank-correlation 0.32β0.39 versus 0.38β0.49 for raw combine. Its in-sample win was largely same-season leakage. So we report it for what it honestly is β better uncertainty and specialist re-rating for mid-board decisions, not a proven predictive upgrade.
Every major finding was handed to adversarial reviewers whose job was to break it. They did, repeatedly, and it changed the conclusions:
Four findings were formally revised; several magnitudes were downgraded to "direction only." A backtest scoreboard scores any ranking on realized draft value, with a naΓ―ve combine-greedy board as the bar and a perfect-hindsight oracle as the ceiling. The gap between them is real but β same caveat as Β§4 β it lives almost entirely in the one clean-linkage season; pooled across the corpus the recoverable per-slot value is a couple of points, not the dozen an earlier draft implied.
The model lost to a coin flip. The good news: we know exactly why, and the two biggest fixes are almost embarrassingly unglamorous.
A backtest is only worth running if it tells you what to do next. Ours does, and the punchline is that the fanciest machinery in this whole post β the IRT, the hierarchical Bayes, the LMSR β is not where the next win comes from. Here's the roadmap, ranked by how much accuracy each lever actually buys.
| Lever | What it fixes | Accuracy gain | Cost |
|---|---|---|---|
| Lean home | Β§6 under-credits home court | 56% β 78% SU | ~free |
| Know the lineup | who dressed vs who was drafted | 56.5% β 65.2% | collect it |
| Trust the market | futures already beat the engine | modest | free |
| More seasons | the Β±16-pt error bars | slow, only cure | time |
Β§6 showed the engine under-credits home court; the season record shows how badly. The model called the home team in just 15 of 36 games β it leaned road far too often β and 14 of its 16 losses were road picks where home won. Add a single home-nudge parameter (about +0.12 to p_home) and the record jumps from 20-16 to 28-8 (78%) β better than blindly picking home, because it keeps the good non-home reads. That Ξ΄ is fit on these same 36 games, so treat the exact 78% with the usual in-sample suspicion β and, per Β§6, the true home edge is a modest ~+15 / ~60% (this season only; it was ~zero historically), so the nudge should be small and season-specific, not a permanent constant. But the direction is bulletproof β the model leaned road too often β and leaning home is the cheapest fix on the board, a recalibration, not a rebuild.
This is the lever the whole post keeps circling. Re-run the game model two ways on the games where we know the real dressed lineup: once blind (the full drafted roster, what we had to use) and once with the actual lineup (the oracle). The gap is enormous:
| Model input | Win accuracy | Brier | Spread RMSE |
|---|---|---|---|
| Blind β full drafted roster | 56.5% | 0.256 | 42.2 |
| Predicted attendance (from history) | 56.5% | 0.289 | 42.4 |
| Oracle β actual lineup | 65.2% | 0.207 | 39.1 |
Knowing who's in the room is worth +9 points of win accuracy β more than the entire ability model contributes β and it flips the predicted favorite in 30% of games. But look at the middle row: the model that predicts attendance from history gains nothing (+0.000). Who shows up on a given Saturday is essentially unforecastable from the past. So this ceiling can't be reached by being cleverer β only by collecting the data. The single highest-value feature we could add to this entire stack is not a model. It's a pre-game form asking each captain who's dressing.
The devigged season futures already out-predict the bottom-up engine, and Β§5's Week-3 blunder was dropping that market blend on an in-sample backtest. Fix: raise the market weight and never again cut it on twelve games. And everything here carries a 95% interval of roughly Β±16 points because n = 36; the only real cure for that is more seasons. No amount of modeling cleverness substitutes for the sample we don't have yet.
What we don't know, stated as plainly as what we do.
A paper that only advertised its wins would be dishonest about a dataset this small. The load-bearing caveats:
The contribution here is not a single number that wins games. It's a ranked, confound-audited, adversarially-tested map of what a science-bowl season does and doesn't let you know β with every magnitude carrying its error bar and every shortcut carrying its caveat. That's the honest version, and it's the only one worth publishing.
We sent the finished post to four hostile readers and told them to break it. They did. Here's the worst of what they found β and what we changed.
None of the four called the paper dishonest β the meta-claim ("almost none of this beats a coin flip; trust directions, not decimals") they largely endorsed. What they found is subtler: even a self-critical write-up smuggles its optimism into the one spot it stops checking β for us, the draft edge and the peak experiment. The fix, every time, was to go check there too. If this reads as sturdier than the first draft, that's four hostile strangers' doing.