はじめに

Apex Legends というゲームをプレイしていて、調子が良いと感じる日と調子が悪いと感じる日で、 どの程度戦績に差があるのか知りたくなりました。

ゲーム内では全期間の戦績とシーズンというゲーム内で定められた期間の戦績を確認できますが、日別の戦績は確認できません。

そこで、TRACKER NETWORK が公開している Apex Tracker API を使用して日別の戦績を記録するレポート API を作成することにしました。

Apex Tracker APIについて

TRACKER NETWORK に登録しアプリケーションを作成することで API Key を発行でき、そちらを使用することで API へのリクエストが可能となります。

こちらでは、何回ゲームをプレイしたか、今までどれだけダメージを与えたか等のトラッカーデータを取得できます。

下記は player’s profile stats を取得できる API のレスポンス結果を一部抜粋したものです。

{
      "type": "legend",
      "attributes": {
        "id": "legend_1"
      },
      "metadata": {
        "name": "Wraith",
        "imageUrl": "https://trackercdn.com/cdn/apex.tracker.gg/legends/wraith-tile.png",
        "tallImageUrl": "https://trackercdn.com/cdn/apex.tracker.gg/legends/wraith-tall.png",
        "bgImageUrl": "https://trackercdn.com/cdn/apex.tracker.gg/legends/wraith-concept-bg-small.jpg",
        "isActive": false
      },
      "expiryDate": "2021-05-28T03:13:21.1241027+00:00",
      "stats": {
        // 現在装着しているトラッカー
        "kills": {
          "rank": null,
          "percentile": 80,
          "displayName": "Kills",
          "displayCategory": "Combat",
          "category": null,
          "metadata": {},
          "value": 844,
          "displayValue": "844",
          "displayType": "Unspecified"
        },
        // 現在装着しているトラッカー
        "damage": {
          "rank": null,
          "percentile": 59,
          "displayName": "Damage",
          "displayCategory": "Combat",
          "category": null,
          "metadata": {},
          "value": 330505,
          "displayValue": "330,505",
          "displayType": "Unspecified"
        },
        "sniperKills": {
          // 昔装着していたトラッカー。valueは更新されていない。
          "rank": null,
          "percentile": 29,
          "displayName": "Sniper Kills",
          "displayCategory": "Weapons",
          "category": null,
          "metadata": {},
          "value": 3,
          "displayValue": "3",
          "displayType": "Unspecified"
        },
        // 装着していたトラッカー。valueは更新されていない。
        "season5Wins": {
          "rank": null,
          "percentile": 78,
          "displayName": "Season 5 Wins",
          "displayCategory": "Game",
          "category": null,
          "metadata": {},
          "value": 15,
          "displayValue": "15",
          "displayType": "Unspecified"
        }
      }
}

こちらは私のアカウントのデータで、レイスというレジェンド(Apex Legends 内で操作できるキャラクターの総称)のトラッカーデータです。

ゲーム中でトラッカーを変更したり、レジェンドの選択を変更しながら何度か API を叩いてレスポンス内容を検証しました。

検証した限りでは、Apex Legends のアカウントに紐づく現在選択中のレジェンドが装着しているトラッカー情報を取得し、レスポンスしているようでした。

また、取得したトラッカー情報は TRACKER NETWORK のサーバーが保持しているようです。

1 度取得したレジェンドのトラッカー情報は、別のレジェンド選択時やトラッカーを変更した場合もレスポンスされています。

戦績レポートAPI

準備として下記 2 点が必要です。

  • ゲーム内でキル数、ダメージ数、プレイ回数のトラッカーを装備した状態にする。
  • レジェンド毎に初期データとして現在のトラッカーデータを取得しておく。

準備ができた状態で、プレイを行なった際 player’s profile stats 取得 API から最新のトラッカーデータを取得します。

player’s profile stats 取得 API のレスポンスと、最新から 1 つ前の日付に取得したデータと比較をすることで、日別のデータを作成することにしました。

実装

下記が実装した API です。

GET /report/upsert

player’s profile stats API へリクエストをし、日別レポートデータの作成、更新します。

ゲーム内で選択されていたレジェンドのデータが DB に存在しなかった場合、初期データとして登録します。

ロジックは下記のような形です。

  1. player’s profile stats API から最新のデータを取得する

  2. 取得したレジェンドの初期データが存在するか確認し、存在しなかった場合は初期データとして登録する

  3. 初期データが存在した場合、取得したレジェンドの日別データから最新の日付のものを取得する

  4. API から取得した最新のデータと DB 取得したデータの差分を本日のデータとして登録、更新する

また、現状はゲームをプレイした際に手動で API を実行する想定です。

GET /report

下記のように日別のデータをレスポンスします。

// GET /report?startAt=20240223&endAt=20240224

{
  "damage": 1000,
  "kills": 5,
  "avgDamage": 333,33,
  "k/p": 1.66,
  "play": 3,
  "date": "2024-02-23"
},
{
  "damage": 500,
  "kills": 1,
  "avgDamage": 250,
  "k/p": 0.5,
  "play": 2,
  "date": "2024-02-24"
}

実装は NestJS で行っています。 まとまり次第 GitHub にリポジトリをアップする予定です。

制約

最新のトラッカー情報とその 1 つ前のトラッカー情報を比較し日別のデータを作成するため、予め各レジェンド毎に現在のトラッカー情報を取得しておく必要があります。

また、player’s profile stats API ではゲームで選択しているレジェンドのみ最新のトラッカー情報が得られます。

そのため、1 日に複数のレジェンドでプレイした場合は、 プレイしたレジェンド毎に player’s profile stats 取得 API から最新の情報の取得する必要があります。

上記の関係から、戦績レポート API にデータ取得用のエンドポイントを設け、手動でデータを作成する形にしました。

ゲームプレイ中、他プレイヤーにトラッカー情報を見せたくない! というプレイヤーは、データ取得の度にゲーム内でトラッカーを付け直す手間がかかります。(自分は見せることに抵抗がないので付けっぱなしにしています)

まとめ

制約は多いですが、ひとまず日別の戦績を記録しレスポンスできる状態になりました。 データを貯めて戦績がよかった日と悪かった日で何が違うか見極めていきたいです。 今後はレジェンド毎の戦績などレスポンスできるように開発を進めていきたいと考えています。