Metric cards: one name, many definitions
football-docs 0.17.0 adds metric cards. Each card lists every published version of a football metric, with its source, a checked quote and, where possible, test code you can run.
Football metrics share names, not definitions. PPDA, xA and progressive passes each have several published versions. Every data provider, website and paper uses its own, and most charts and articles never say which one they used.
Here is how big the gap is. Take the 2022 World Cup final and apply each published rule to the same StatsBomb open data. The events are identical, so every difference below comes from the definition alone.
| Argentina, 2022 World Cup final | Value |
|---|---|
| PPDA, StatsBomb (Hudl) formula | 7.42 |
| PPDA, Colin Trainor’s 2014 formula | 9.77 |
| PPDA, Opta Analyst’s formula | 6.81 |
| Progressive passes, Wyscout’s rule | 97 |
| Progressive passes, FBref’s rule | 64 |
| Progressive passes, Opta Analyst’s rule | 36 |
| Progressive passes, American Soccer Analysis’s rule | 33 |
So when someone writes “Argentina’s PPDA was 7.4”, you can’t check it, and you can’t compare it with a number from another site.
This gets worse with AI agents. Ask one what PPDA is and you get one confident definition with no source. Often it’s a blend of two versions, and the agent can’t tell you that.
What a metric card is
A metric card is one checked page per metric, inside football-docs. Each card has:
- Every published version, each with its own ID, such as
ppda.statsbomb-hudlorppda.trainor-2014. Each version gives its formula, which events it counts and which part of the pitch it uses. No version is called the correct one. - A source and a short quote for each version, checked word for word against the original (a glossary, a paper, a blog post or the provider’s own code).
- The origin. For example, xT comes from Karun Singh’s 2019 blog post, and the Wayback Machine has held that page since 22 February 2019.
- Caveats that change how you read the numbers. Hudl StatsBomb’s player and team xG leave penalties out, but FBref’s and Understat’s include them. Each provider gives a penalty one fixed xG (Opta 0.79, Wyscout 0.76, Hudl StatsBomb 0.78). FBref removed its Opta advanced data on 20 January 2026, so FBref versions describe numbers that are no longer on the site.
- Reference code with test values for 24 versions: short Python that runs on free StatsBomb open data, with the expected answer for each team in the 2022 final. The tests run on every change.
The first eleven cards are xG, npxG, xG assisted (FBref’s xAG), xA (the pass-level kind), PPDA, progressive passes, progressive carries, xT, VAEP, field tilt and pass completion.
Your agent gets two new tools:
get_metric("ppda") -> the whole card
get_metric("ppda.trainor-2014") -> one version
list_metrics -> every card and version
The cards also come up in ordinary search_docs results, and card fixes reach your install with the daily docs update, with no new version needed.
What you can do with it
- Cite a number exactly. Write “PPDA 7.42 (
ppda.statsbomb-hudl)” and anyone can find the definition behind it. - Explain why two sites disagree. If one site says 64 progressive passes and another says 36, the card shows which rule each one uses and where they differ. In that case: FBref counts a completed pass that moves the ball at least 10 yards towards goal (measured from its furthest point in the last six passes) or into the penalty area, unless it starts in the defending 40% of the pitch. Opta Analyst counts a completed open-play pass in the attacking two-thirds that moves the ball at least 25% closer to goal.
- Check your own code. Write PPDA for StatsBomb data, run it on the final, and compare with 7.4222. If you get something else, the card tells you which counting rule to look at.
- Change data provider without surprises. Moving from Opta to StatsBomb? The cards show which metrics change meaning between the two, from penalties in xG to which passes count.
- Keep your AI agent honest. This is the main reason the cards exist. An agent (nutmeg, for example) looks the metric up by ID instead of making a definition up, and puts that ID next to every claim it makes. If it says “xA”, the cards make it say which of the two xA metrics it means.
Why not just use…
- An AI chatbot? One blended definition, no source, and no way to know which version you got.
- The provider’s glossary? Each glossary covers its own version only, some are silent on the edge cases, and none compares itself with the others.
- FBref? Its Opta advanced data is gone, and its definitions were one-line column tooltips.
- A blog post or Wikipedia? Usually one version, often unsourced, sometimes out of date.
- A library such as socceraction? Great for code, but it gives you one way to compute a metric, not the map of published versions and where each came from. (socceraction is also no longer actively developed.)
What the cards add is the comparison in one place, with every claim tied to a checked source.
What it doesn’t do
- It gives definitions, not data. It won’t compute metrics for your matches. The 2022 final values are there to test the reference code.
- Closed models are described, not rebuilt. Opta’s xG and xA, for example, have no reference code, because the models aren’t public.
- VAEP has no test values yet. A version trained on public data, the way socceraction’s own example notebooks do it, comes in a later release.
- Event data only, for now. Tracking metrics (sprint distance, pitch control and more) are next, then cards that describe closed models such as PSxG and OBV.
Try it
claude mcp add football-docs -- npx -y football-docs@latest
Then ask your agent something like “which PPDA does Hudl use, and how is it different from Trainor’s?”
Is there a metric you’d like a card for, or a definition I’ve got wrong? I’m taking requests for the next batch.