Matches
230
WC 2018 & 2022 · Euro 2020 & 2024
On-ball actions
500,199
17 SPADL-style action types
Goals priced
600
incl. own goals · shootouts excluded
Score base rate
1.01%
P(goal within k = 10 actions) · concede 0.19%

The action theatre

The top of the market. Play through the most valuable single touches among 500,199 candidates — then switch reels to the best touches that weren’t shots, and to the fourteen actions that decided Argentina 3–3 France.

Every one of the fifteen highest-valued touches in the corpus is a goal — the top of the list runs from Milan Škriniar’s volley against Poland (+0.975, P(score) 1.7% → 99.2%) down to Roman Yaremchuk at +0.960.1 The second reel is where the model gets interesting: Kylian Mbappé’s 33rd-minute recovery against Peru is worth +0.947 — the most valuable non-shot in four tournaments — and John McGinn’s pass against Croatia moved Scotland’s chance of scoring from 9.8% to 98.1% before a boot ever swung.

The third reel replays the swings of the 2022 final in match order: Messi’s penalty (+0.770), Di María’s finish (+0.888), Kolo Muani’s 67th-minute miss (−0.347), Mbappé’s equaliser (+0.936), Messi’s extra-time rebound recovery (+0.486) and finish (+0.447) — and Gonzalo Montiel’s handball, priced at −0.395 almost entirely through the concede term.

1 Scoring moves P(score) to ≈ 0.99 by definition, so finishes monopolise the raw top of the list. Breaking up a 2% attack is worth at most ≈ +0.02, which is why defenders surface in per-90 sums, not single actions. Very high recovery values (Mbappé’s +0.947) are rebound credit — this lite build cannot split credit with the shot that caused the chaos; Atomic-VAEP can.

The going rate of a touch

Average the half-million actions by type and a price list appears. Penalties are their own economy; so, in the other direction, are direct free kicks — only 4.2% of 212 attempts scored, so stepping up to shoot one actually cost goal probability on average.

Penalty kick
+0.210
per attempt · n = 81 · 70.4% scored
Direct free kick
−0.027
per attempt · n = 212 · 4.2% scored
Open-play shot
+0.016
per attempt · n = 5,394 · 9.2% scored
Pass
+0.0011
per attempt · n = 215,845 · 84.2% completed

Two things goal-and-assist counting never shows. First, defensive work carries real value here: a tackle averages +10.7 goals per thousand — on par with a cross — and a keeper claiming a cross earns most of its +13.8 through the concede side of the ledger. Second, the humble pass is worth just over one goal per thousand attempts — volume, not price, is how midfielders accumulate value.

The leaderboard: value per 90

Sum every touch, divide by minutes. Wout Weghorst leads all four tournaments at +0.844 per 90 — an impact-sub profile built on 450 minutes — ahead of Ivan Schranz (+0.834) and Karim Benzema (+0.821). Lionel Messi sits 14th at +0.561, with by far the most exposure in the top 15: 1,113 minutes and 1,433 actions.2

The tournament tabs each tell their own story: Bukayo Saka tops WC 2022 at +0.893 in 291 minutes, Xherdan Shaqiri owns Euro 2020 (+0.872), and Denis Cheryshev leads WC 2018 at +0.719 despite a −0.152 defensive column — the framework happily shows you both sides of a player’s ledger at once.

2 Leaderboards require ≥ 270 minutes. Per-90 rates reward short, hot tournaments; treat the minutes column as part of the answer, not a footnote to it.

Where VAEP and xT disagree

Run Karun Singh’s expected threat on the same events and rank the same 705 players (≥ 270 minutes) both ways: the two frameworks agree far less than you’d guess — Spearman ρ = 0.30. Niclas Füllkrug is the poster child: VAEP rank 21, xT rank 702. A pure poacher is invisible to a ball-progression model.3

The disagreement runs both ways. David Alaba is xT’s #8 player of the four tournaments but VAEP’s #638: deep progression that rarely turns into a goal within ten actions, plus defensive risk that xT never counts. Raphinha is xT #2 and VAEP #541. In the other corner, Füllkrug’s xT per 90 is actually negative (−0.058) while his VAEP sits at +0.507. Messi is the rare star both frameworks agree on: VAEP rank 14, xT rank 16.

3 The axes are different currencies: xT/90 values only completed passes and carries, by where they move the ball and nothing else; VAEP/90 values all on-ball actions and includes an explicit concede term. That is precisely why the scatter is a cloud, not a line.

Is the model honest?

VAEP consumes raw probabilities, not classifications, so calibration is the whole game — the base rate of “goal within ten actions” is 1.01%. On a strict temporal split (train WC 2018 + Euro 2020, test WC 2022 + Euro 2024) this lite build lands on the published benchmark: Pscore AUC 0.807 against the paper’s typical ≈ 0.80.

P(score) · AUC
0.807
test base rate 0.96%
P(score) · log-loss
0.0439
lower is better
P(score) · NBS
0.883
Brier ÷ base-rate Brier · < 1 beats baseline
P(concede) · AUC
0.779
test base rate 0.18%
P(concede) · log-loss
0.0120
lower is better
P(concede) · NBS
0.955
the harder task — rarer label

Read the reliability curve honestly: it is excellent exactly where the money is. In the bin holding 250,952 everyday actions the model predicts 0.71% and reality delivers 0.73%; at the top, post-shot states predicted at 97.3% come true 96.6% of the time. In between it is overconfident — states priced at 54.7% scored only 16.7% of the time — but that middle is thin air: 42 actions out of half a million.

And read “lite” honestly too. The KDD-2019 original uses the full 22-type SPADL vocabulary, ~150 features and CatBoost, trained on whole club seasons; this build uses 17 action types, ~53 features and two HistGradientBoosting classifiers on 115 international matches, with the label window truncated at period end. That it still reproduces the paper’s AUC and produces face-valid leaderboards is the point of the exercise — the framework, not the horsepower, is doing the work.

The port: same model, club football

Same model family, different corpus: the framework above, refit on — Big-5 league matches from 2025/26 — — on-ball actions reconstructed from minute-resolution Opta tables, not read from an ordered event feed. That word is this section’s honesty headline: the stream order is inferred, and the ordering witness says how well. A completed pass’s known receiver appears on the very next same-team touch — of the time, and within ten touches — of the time.

P(score) · AUC
—
test base rate —
P(concede) · AUC
—
test base rate —
P(score) · NBS
—
Brier ÷ base-rate Brier · < 1 beats baseline
P(concede) · NBS
—
the harder task — rarer label

The rest of the register, straight from the payload’s meta: — of the stream is synthesized carries — inserted wherever consecutive same-team actions leave a coordinate gap, a proxy for touches the minute tables never record. Own goals are corrected through the Understat shot join (— flagged; — rebuilt scorelines still disagree after the fix). The feed carries no body part — omitted rather than guessed — and no seconds, so every time feature rides a rank-within-minute proxy.

The boards below speak the scout register — players at ≥ 900 minutes, the same pool every other page uses — and every name links through to its full dossier. The season leader is — at — per 90.

Keepers top the defensive board, and the register says why before you read it as praise: the defensive term tracks save volume, not save quality — a busy keeper behind a porous defence out-earns a better one who sees less of the ball. The caption on the table is the pipeline’s own caveat, quoted verbatim.

What this rating is allowed to do downstream, verbatim from the payload: “—”