Run your own numbers. This is the same audited dataset the whole site is built from โ every custom, ranked and quick-play game we've harvested since Feb 2025. Download it, hand it to Claude (or Excel, or Python), and check our math. If you find something we got wrong, the record is open.
Deduped and analysis-ready: date, mode, map, player, primary hero + role, result, K/D/A, damage, healing, MVP/SVP. Humans only, best source per game (full lobby detail where we have it, feed otherwise).
Everything, raw: matches, match_players (incl. bots), hero_lines (per-hero playtime within each game), rank_seasons, players. Claude Code and Claude desktop can query SQLite directly.
Every account's rank arc across seasons (peak tier + rank score). Cross-platform ranks are separate ladders โ compare with care.
is_bot=1 rows exist in the DB โ filter them, or use games.csv which already did).source='lobby' and source='feed'). Lobby is authoritative (full stats); feed only for kills/deaths/result. Never sum across both โ games.csv has already picked one per game.hero_lines), never the hero someone ended on. Feed-only games fall back to the first hero listed.team is a within-match label only. Lobby rows use 1/2, feed rows use tracker's 0/1 โ either way it just groups teammates inside one match; team numbers mean nothing across matches or sources.mode='custom-game'. The 10 free-for-all matches are excluded from every per-player stat, not just win rates โ games played, K/D, kills/game, MVP and SVP totals all skip them, because an FFA scores the winner's team as a win and everyone else as a draw, which would quietly inflate draw counts and deflate losses. Consequence to know: the site headline says 688 customs but no individual's games-played can exceed 678, and a couple of MVP totals are lower than a raw DB query returns (Donovan 4 rather than 6).meta.detailThrough). Right now those two dates are the same night (2026-08-21), so the gap is zero and the two windows agree โ but check this number rather than assuming, because the gap reopens any week the match-detail API lags. Don't compare a player's "last 90 days" record against their "last 90 days" Iron Man numbers and expect the same denominator.mode='void-lobby', so they're excluded from every stat but still auditable. Single-player customs with real stats are kept โ the test is activity, not headcount.We pick the teams every week, and we pick them to be fair. That quietly breaks win rate: balance a weaker player onto a strong side and their win% climbs toward 50, split the best players apart and theirs falls toward 50. Everyone converges on 50% and the number stops measuring the player. Pair ("chemistry") win rates are worse, because who you're paired with is exactly the thing being chosen.
So the site also publishes data/strength.json โ one rating per player from a Bradley-Terry model (ridge-penalised logistic regression, the same family as chess ratings, generalised to teams) fit across every decisive custom at once. Each player's rating is estimated in the presence of their teammates and their opponents, so placement cancels out. It also composes, which means it can price a line-up that has never been played.
Fields: strength (points, 0 = lobby average), lo/hi (90% bootstrap range), trueWin (win% if we swapped an average player for this one), rawWin (plain win rate), bias (rawWin โ trueWin: positive = the balancer has been flattering you). Also current (a recent-form rating, null when someone has too few recent games โ that is an honest "unranked", not a zero), recentGames, halfLife/ridge/calShrink (the fitted hyperparameters โ confidence is shrunk because the raw model overstates blowouts), regimeEqual/regimeUneven/regimePooled (accuracy and forward log-loss split by even vs bot-padded lobbies, where 0.693 is a coin flip and lower is better), and caveats โ the model stating its own limits in plain English, including where it has no discrimination at all. Built by data/strength_model.py. Group beliefs about never-played comps live in that script's priors.json alongside it in the repo (not published here, since it is an input rather than a result).
Paste this prompt with the CSV (or point Claude Code at the URLs) and it inherits our conventions instead of re-learning our old bugs:
I'm analyzing my friend group's Marvel Rivals data from marvelgooners.com/data/ (games.csv; full SQLite at rivals.db). Rules the numbers must follow: - One row per player per game (already deduped). mode='custom-game' = our Friday customs; 'competitive' = solo ranked; exclude other modes unless asked. - Win rate = wins / (wins+losses). Draws are NEUTRAL (excluded from the denominator, but report them in records as W-L-D). Per-game rates (kills/game, MVP rate, attendance) DO include draws. - Teams were deliberately balanced, so win rate is confounded by placement โ if you want player strength, fit a Bradley-Terry model on team compositions rather than averaging win rates. - Blank damage/healing = missing lobby detail (newest games), NOT zero โ exclude those games from damage/heal averages. - primary_hero is playtime-based. hero_role: Tank / DPS / Healer. - Win rate is a TEAM outcome (teams are re-balanced weekly to be fair) โ don't present it as individual skill without saying so. - Cross-platform ranked ladders aren't comparable (PC and console queue separately). Sanity anchors to verify your load: 688 custom games, 18 tracked players, record runs 2025-02-09 โ 2026-08-27.
Data regenerates with every site update โ same pipeline, same audits. Fine print: this is our private lobby's harvested record; be chill with it. Receipts live at marvelgooners.com.