• v3.10.0 dda79c2c24

    v3.10.0
    All checks were successful
    CI / build-and-test (push) Successful in 1m59s
    Stable

    joeyr released this 2026-07-30 20:28:26 -05:00 | 27 commits to main since this release

    Everything here came out of one real Classic Rift game, watched live through the
    Live Client Data API. The mode was already detected correctly (v3.9.2); what
    this release fixes is everything downstream that quietly assumed live-roster
    data — most of which reported a confident wrong number rather than staying quiet.

    Fixed

    • Every lane's gold difference read +0 for an entire game, and the team-gold
      bar with it.
      Classic Rift namespaces items exactly the way it namespaces
      champions: 770000 + base id, so Doran's Ring is 771056. The committed cost
      table was generated from patch 16.12.1 — three patches before the mode shipped
      — so not one of the 69 items seen across a 34-minute game had a known cost.
      Every inventory summed to 0, so every difference was 0 − 0, and the overlay
      stated "dead even" on all five lanes while the game was decidedly not.

      The root cause was not the stale table, which is merely how it surfaced.
      getItemCost returned 0 for both "this item is free" and "no idea what this
      item is", and itemGold summed straight through that. Absence now means
      unknown: the generator keeps zero-cost entries (>= 0, not > 0) so a
      trinket is a real 0, and itemGold returns null if any held item cannot be
      priced. A partial sum was the worst available answer — it reads as "this player
      is behind" rather than "we don't know" — so it is all-or-nothing, and null
      propagates to on the lane rows, the gold/min metric, and the team-gold bar,
      which now hides rather than drawing a 50/50 split beside a meaningless +0.

      Regenerating against 16.15.1 also picked up three live items whose prices had
      drifted since 16.12.1 (Bastionbreaker 3200 → 3000, Protoplasm Harness
      2500 → 2600, Yun Tal Wildarrows 3100 → 3000), which had been skewing normal
      games too.

    • The benchmark harvester ground a full game at 0/150 against a classic
      champion id.
      Match-V5 reports live ids, so a 60xxx subject matches nothing
      it will ever return. HarvestQueue.enqueue now refuses those ids outright and
      logs harvest.skipped_classic; the Riot key is shared with the nightly crawl,
      so the wasted budget was not free.

    Changed

    • Roster detection gained two stronger signals, and the reasoning behind
      ignoring gameMode was wrong.
      The previous comment dismissed the field
      because ordinary Summoner's Rift reports "CLASSIC" — true, but it does not
      follow that the field is useless. Classic Rift reports "JADE", matching
      the Jade_ champion aliases, which makes it a clean mode-level discriminator.
      Detection now tries rawChampionNamegameModemapNumbermapName,
      strongest first, and mapNumber: 453 is preferred over "Map453" because it
      is the id rather than a rendering of it. All four were observed together in the
      real game; the redundancy is for the payload shapes Riot ships next. CLASSIC
      is still explicitly rejected, with a test pinning it.

      The Map453 spelling that v3.9.2 guessed at is now confirmed rather than
      assumed.

    Added

    • The in-game tracker sits 120px higher in Classic Rift. Its HUD is the
      taller 2009-era layout, so a bottom-anchored panel at the normal 12px margin
      overlapped the scoreboard and champion frame. The detected roster now travels
      on the live-metrics IPC message, and only the bottom edge moves — side margins,
      top-anchored corners, and live games are all untouched.

    Known gaps

    • Champ select still resolves nothing in Classic — counters, tier badges,
      defensive bans, runes and item builds all fall through to op.gg, which is
      queried with type=ranked and the jade_* slug. op.gg does publish the mode
      under type=classic with the base slug, so this is fixable and is not a
      limitation of the source; it is simply not in this release.
    Downloads