Every Ball Ever

How we computed this

Every number in the story traces to an artifact built by a deterministic pipeline from public ball-by-ball data — same input, same bytes out, every time. This page is the honest core: what we counted, what we excluded, and why. It grows with each release.

The corpus

Everything starts from Cricsheet’s ball-by-ball JSON: 1,243 IPL matches (2008–2026) and 88 WPL matches (2023–2026) — 1,331 matches across 19 IPL seasons and 4 WPL seasons, with 937 players counted by registry ID rather than by name, so one player written two ways stays one player and two players who share a name stay two. Every count the story shows is read from the pipeline’s emitted artifacts (meta.json and friends) — the artifact, not the prose, is the source of truth; if the two ever disagree, the artifact wins and the copy changes.

What counts as a ball

Every legal and illegal delivery recorded by Cricsheet — except super overs. The corpus holds 316,388 deliveries; 189 of them belong to the 17 tie-match super overs (36 super-over innings), and those 189 are excluded from the field and from every ball-level stat. So the number the screen shows — 316,199 — is exactly the number that’s there. House rule: never show a number the pixels contradict.

Conventions used throughout: wides don’t count toward a batter’s balls faced (the batter never faced them); no-balls do. A dot ball is a legal delivery with zero total runs. Strike rate is runs off the bat per 100 balls faced.

One season, one label

Cricsheet labels a few editions with split years; the pipeline collapses each to its edition year — 2007/08→2008, 2009/10→2010, 2020/21→2020 — so “2008” means the same season in every chart, caption, and buffer. That normalization is why the piece counts 19 IPL seasons, 2008 through 2026, with no gaps and no doubles.

Era bands

When the story says “then vs now,” then is IPL 2008–2010 and now is IPL 2023–2026: the league’s first three seasons against its latest four. Curves that need finer resolution use five IPL bands — 2008–10, 2011–15, 2016–19, 2020–22, 2023–26. Bands exist because single seasons are noisy; pooled, the first-ten-ball samples run from about 20,100 balls (2008–10) to about 33,900 (2023–26), enough that a curve’s shape is signal rather than luck.

The WPL is pooled as one band — four seasons, 88 matches, 20,642 deliveries, about 10,200 first-ten balls. It is a young league and its numbers will move; the story says so wherever they appear. Each scene’s ⓘ footnote repeats the band definitions and sample sizes it relies on.

The out-rate, ball by ball

In the story we call it “how often a batter gets out on exactly that ball.” The technical name is a discrete-time hazard curve, estimated Kaplan-Meier-style: dismissals at ball n divided by batter-innings that reached ball n. Not-out innings are censored — they count while observed, then stop counting — as are the corpus’s 10 retired-hurt and 5 tactical retired-out innings. Run-outs count against the batter given out, non-strikers included, at their own ball count. The out-rate is risk per ball; strike rate is runs per ball. They move independently — which is exactly Chapter 1’s point.

Aerial attempts (a proxy)

The public record doesn’t say whether a batter swung hard, so we use a proxy: aerial attempts = sixes + caught dismissals (caught-and-bowled excluded), and execution = sixes as a share of attempts. Caught includes keeper and slip edges — noise, but stable noise, so era-to-era comparisons hold even though any single number carries this caveat. True shot-level intent would need ball-tracking data that isn’t public.

The draw

The cold-open truth series counts 200-run innings per season — any innings, either batting side, super overs excluded. The 2008–2012 segment comes pre-drawn from the real values to anchor the sketch. The reveal’s copy branches are decided by documented constants applied to your drawn values, evaluated in a fixed order; your sketch is stored only in your browser. Aggregated sketch statistics may be published in a later release.

Payoff cards

Team payoff cards are strictly template + per-team JSON emitted by the pipeline — never hand-authored. A snapshot harness asserts all 16 variants (10 IPL + 5 WPL + neutral) exist and are non-degenerate, including the designed empty states for franchises born after 2010. Franchise renames merge histories: Delhi Daredevils→Delhi Capitals, Kings XI Punjab→Punjab Kings, Royal Challengers Bangalore→Bengaluru. Defunct franchises (Deccan Chargers, Kochi Tuskers Kerala, Pune Warriors, Rising Pune Supergiant, Gujarat Lions) keep their own identities — their balls are on the field; they just aren’t pickable.

Rendering honesty

The render loop stops whenever nothing moves (demand-mode rendering): “the field dims” means the GPU rests. Readers with reduced-motion preferences get live-rendered end-state jump-cuts — the same renderer, no interpolation, no pre-baked frames — so team colors and personalization survive. Layout positions are computed on your device from small per-ball attributes; nothing heavier crosses the wire, and a payload ledger in the build enforces byte budgets on every artifact the page fetches.

Licenses & credits

Ball-by-ball data from Cricsheet, used under the Open Data Commons Open Database License (ODbL) 1.0. This project’s derived datasets — every JSON and binary buffer the page fetches — are shared under the same license, as ODbL’s share-alike terms require. Built with SvelteKit, three.js, and GSAP.

The code is open: github.com/lyndonkl/iplprogress — the deterministic pipeline, the payload ledger, and the snapshot tests behind every number on this page live there.

← Back to the field