• v0.20.0 0ab0641d96

    0.20.0
    All checks were successful
    CI / gate (push) Successful in 43s
    CI / image (push) Successful in 16s
    Stable

    joeyr released this 2026-08-04 16:49:16 -05:00 | 184 commits to main since this release

    Added

    • data/champion-builds.json — what players bought, and in what order. A
      new published artifact and a new URL, and the first one in this service that
      costs additional Riot requests.

      It carries two measurements from populations an order of magnitude apart,
      and the entry splits so each states its own games and wins:

      • owned — the final inventory, from every recorded match (~1,700 a
        night). item0item6 have been captured since 0.17.0 and cost nothing.
      • order — the purchase sequence, from the ~12% of matches a match-v5
        timeline was fetched for.

      A single games would let a reader compare a 1,700-game figure against a
      200-game one without noticing. order.games: 0 is a real state, not a hole:
      no sampled match contained that champion-role.

      Completed items and boots are reported separately, because a boot is a build
      slot rather than a legendary. Classification comes from Data Dragon's
      item.json at build time, never at capture — the version used is published as
      generatedFrom.itemVersion.

      Full six-item builds are deliberately not published. At ~100 games per
      champion-role nearly every complete build observed is unique, so publishing
      them all is ~1.5 MB of games: 1 rows nobody can use. That is not the
      filtering CLAUDE.md forbids — that rule is about dropping measured rows from a
      bounded aggregation, and this is declining to publish an unbounded one,
      the same reasoning that makes a rune combo a tree pair rather than an exact
      nine-perk page.

    • Timeline sampling, and participant_stat.item_order / item_times to
      hold what it collects. TIMELINE_MAX_REQUESTS (200) and
      TIMELINE_TARGET_GAMES (100), plus BUILDS_ENABLED / BUILDS_PATH /
      BUILDS_OUT and a builds row in publish_state.

      The spend is targeted, not random. The match is fetched first, so its ten
      champion-roles are known before the decision; a timeline is fetched only while
      the least covered of them is under target. Champion-role popularity spans
      two orders of magnitude, so a uniform draw would collect a nine-hundredth Jinx
      build while Ivern jungle sat at four.

      Participants are joined to the timeline by puuid, never by position
      the documented positional correspondence would silently credit each champion
      with somebody else's build if it ever changed. The puuid is read and
      discarded; the privacy rule that no puuid is ever written is unchanged, and a
      test asserts it.

    Changed

    • The nightly match count drops by up to ~12%, and this is the only setting
      in the service that does that. A timeline is a second request against the same
      key, so 200 of them is 200 matches not crawled — and every artifact reads
      those rows. TIMELINE_MAX_REQUESTS is a hard count rather than a ratio for
      exactly that reason.

      TIMELINE_MAX_REQUESTS=0, or BUILDS_ENABLED=false, gives the budget back.
      The first keeps the owned half publishing on its own; the second stops both.

    Notes

    • One assumption in the timeline parser is documented rather than observed.
      ITEM_UNDO is implemented per Riot's documented convention — the bought item
      in beforeId, afterId: 0 — but no captured payload with a real undo could
      be checked, because the key available at implementation time returned 403. So
      the crawl counts and logs unmatchedUndos per window instead: it should be
      ~0, and if it tracks the undo count then the fields are the other way round
      and undone purchases are being published as real ones. Worth reading on the
      first night this runs.
    • Watch the match count on the first night, since this is the release that
      trades it. It should fall by about 12% and no more; the cap is hard.
    • No consumer change is required. lol-companion does not fetch this URL.
    Downloads