LOLのチャンピオンの「よく使用されているポジション」を取得する技術

League of Legends(以下LoL)というゲームをご存知だろうか。世界で一番アクティブユーザーが多いらしいゲームでまじで面白いのでやったほうが良い。
今回の記事はLOLを知っている人向けの記事です。

「チャンピオンの使用頻度の高いポジション」が取得できない

このLOLというゲームはキャラの名前やスキルの説明、プレイヤーの状態等色々なものがWeb APIで公開されている。しかし、肝心の「チャンピオンの使用頻度の高いポジション」が取得できない。 実際にDataDragonからチャンピオンの一覧を取ってくるとAkaliはAssasinだしAatroxはFighter、Tankだ。

ddragon.leagueoflegends.com/cdn/13.1.1/data/en_US/champion.json

{
	"Aatrox": {
		"version": "13.1.1",
		"id": "Aatrox",
		"key": "266",
		"name": "Aatrox",
		"title": "the Darkin Blade",
		"blurb": "Once honored defenders of Shurima against the Void, Aatrox and his brethren would eventually become an even greater threat to Runeterra, and were defeated only by cunning mortal sorcery. But after centuries of imprisonment, Aatrox was the first to find...",
		"info": {
			"attack": 8,
			"defense": 4,
			"magic": 3,
			"difficulty": 4
		},
		"image": {
			"full": "Aatrox.png",
			"sprite": "champion0.png",
			"group": "champion",
			"x": 0,
			"y": 0,
			"w": 48,
			"h": 48
		},
		"tags": [
			"Fighter",
			"Tank"
		],
		"partype": "Blood Well",
		"stats": {
			"hp": 650,
			"hpperlevel": 114,
			"mp": 0,
			"mpperlevel": 0,
			"movespeed": 345,
			"armor": 38,
			"armorperlevel": 4.45,
			"spellblock": 32,
			"spellblockperlevel": 2.05,
			"attackrange": 175,
			"hpregen": 3,
			"hpregenperlevel": 1,
			"mpregen": 0,
			"mpregenperlevel": 0,
			"crit": 0,
			"critperlevel": 0,
			"attackdamage": 60,
			"attackdamageperlevel": 5,
			"attackspeedperlevel": 2.5,
			"attackspeed": 0.651
		}
	}
}

別に間違っているわけではないものの、いつも見ているチャンピオンのピック画面のように「前パッチの使用頻度の高いポジション」でグループできる情報が欲しい。

op.ggだってfow.krだってチャンピオンはレーン別にグループされている。LoLに関するサービスを作るときにこの情報は必須といっていいだろう。
ポジションに関する情報は前パッチから集計している動的な情報らしいがRiotGamesAPIにはそんな情報をとれるエンドポイントはないしDataDragonからも取得できない。
この記事ではそんな「使用頻度の高いポジション」を取得する方法を解説する。

サンプルアプリケーション

https://optube-qwyng.vercel.app
↑はNext.jsでつくった自作アプリで「使用頻度の高いポジション」でチャンピオンをグループしている。YoutubeでLOLの動画を検索できるアプリで、最新パッチ以降の日付や、チャンピオンの英名や韓国名で検索できて便利なのでぜひ使ってみてほしい。

使用頻度の高いポジションの取得の方法

「使用頻度の高いポジション」のソースはLOLのクライアントが利用しているJSファイルから取得できる。
このJSファイルはCDragonという色々Riotが配布してるアセットをスクレイピングして公開している組織から取得できる。
https://raw.communitydragon.org/latest/plugins/rcp-fe-lol-champion-statistics/global/default/rcp-fe-lol-champion-statistics.js

このCDragon、グレーゾーンらしいがRiotDeveloperポータルには認められているらしく、これを使っているからAPIキーが止められるとかは無いらしい。ハッキングとか悪意のある目的では使うのはまずいだろう。
GitHub - CommunityDragon/Docs: Documentation of files and formats handled by CDragon

皆さんのLOLをインストールしているディレクトリにも Riot Games\League of Legends\Plugins\rcp-fe-lol-champion-statisticsのようなフォルダが存在していると思う。ここにはassets.wadというファイルが存在しているがそれをいい感じにパースしたものをCDragonが公開してくれていると思われる。

このJSファイルにはチャンピオンのkey(Ddragonのプロパティ名)とポジションのピックレートがマッピングされているmapオブジェクトが書いてある。

{a.exports={BOTTOM:{15:.01759,18:.03612,21:.03514,22:.03747,29:.0315,51:.09918,67:.04282,81:.10527,96:.01197,110:.03929,119:.03307,145:.10065,202:.08399,221:.03265,222:.03872,236:.05258,360:.05495,429:.01279,498:.02021,523:.02099,895:.02},MIDDLE:{1:.00613,3:.00782,4:.01097,7:.01869,8:.02084,13:.01332,34:.01115,38:.03712,39:.0323,41:.01099,42:.00577,45:.01648,50:.01106,55:.04834,61:.00832,68:.00533,69:.00851,84:.04306,90:.01998,91:.01792,99:.02574,103:.02292,105:.01694,110:.01324,112:.03194,115:.00637,127:.01064,131:.01056,134:.02633,136:.00344,142:.01352,157:.06195,163:.00423,166:.01306,238:.06248,245:.01355,246:.01357,268:.01081,517:.03969,518:.00521,711:.02411,777:.04426},JUNGLE:{5:.00863,9:.01553,11:.03873,19:.0279,20:.01736,28:.0227,30:.007,32:.01005,33:.02859,35:.03268,48:.00964,56:.01707,57:.01239,59:.01034,60:.02199,62:.01485,64:.05305,72:.00393,76:.01367,77:.03483,78:.00653,79:.00799,82:.02084,102:.00978,104:.03291,106:.00742,107:.02022,113:.01739,120:.03105,121:.02907,131:.03478,141:.03873,154:.02219,163:.00387,200:.01908,203:.0307,234:.0362,238:.01673,245:.03868,254:.02313,421:.00676,427:.00465,517:.05176,876:.02119},TOP:{2:.0111,6:.0113,10:.01273,14:.02184,17:.02087,19:.01396,23:.01288,24:.03007,27:.01037,31:.01102,36:.04419,39:.02747,41:.04528,54:.01387,58:.01969,68:.00475,75:.02528,79:.00986,82:.03633,83:.0123,84:.01464,85:.00531,86:.0235,92:.02334,98:.01747,106:.0091,114:.04415,122:.04776,126:.01187,133:.00602,150:.01106,157:.01351,164:.0266,223:.01125,240:.00942,266:.05326,420:.02037,516:.01459,777:.02164,875:.03746,887:.01417,897:.03748},SUPPORT:{12:.0152,16:.02973,22:.02486,25:.03516,26:.0196,29:.01459,32:.01839,37:.01648,40:.02234,43:.03578,44:.00747,50:.02761,53:.03705,57:.01161,63:.02242,74:.01677,80:.01283,89:.02397,99:.06711,101:.02288,111:.02979,117:.04216,143:.01677,147:.01724,161:.01218,201:.00885,235:.03293,267:.05159,350:.04175,412:.05621,432:.01635,497:.01434,526:.00825,555:.04461,888:.01887}}},function(){}]);

このmapを良い感じにパースすればどのチャンピオンがどのポジションで使われているかを取得できる。
↓は実際にサンプルアプリケーションで使っているTypeScriptでパースしているコード。 https://github.com/QWYNG/optube/blob/f67340d5885bbab6adc0850c1e48e5d2f459b096/lib/lol.ts#L67

例えばAshはサポートでもボットでも使われているのでその2つのポジションのピックレートがmapオブジェクトに存在している。世界にはAshでトップに行く人間もいるだろうがこのデータには含まれていないようだ。一定以上のピックレートがないと記載されないのだろう。

参考になるレポジトリや記事

この方法を見つけたときに参考になったレポジトリや記事を書いておく。

まとめ

世の中の先行研究に感謝。日本語でRiotAPIのこと書いてある記事もっと増えてほしい。RiotGamesさんオファー待ってます。
実際OP.GGとかどうやってポジション取得してるんでしょうね?