IGDB APIの使い方：ゲーム情報取得のコツと注意点

## はじめに

ゲーム関連のサービスを開発する際、ゲームに関する情報を取得したい場合があります。そんな際、[IGDB](https://www.igdb.com/)の提供するIGDB APIが有力な選択肢となります。この記事では、IGDB APIの基本的な使い方から、実際に使用する上でのコツや注意点までを紹介します。

[公式ドキュメント](https://api-docs.igdb.com/)が充実しているので、詳細な使い方はそちらを参照してください。ここでは、特に日本語での情報取得や、不要なデータの除外方法など、実際に使用する際、役立つ情報に焦点を当てています。

## IGDB APIとは

IGDBは、Internet Game Database（インターネット・ゲーム・データベース）の略称で、[https://www.igdb.com/](https://www.igdb.com/) で運営されています。もともとはユーザー主導のデータベースでしたが、2019年にゲーム配信プラットフォームのTwitchに買収されました[^1]。現在は、Twitchの管理下でAPIが提供されています。

[^1]: [Twitchがゲームデータベースサイトの「IGDB」を買収、検索機能の改善が目的 - GIGAZINE](https://gigazine.net/news/20190918-twitch-acquires-igdb/)

## 基本的な使い方

IGDB APIの基本的な使い方については、[こちらの記事](https://maku.blog/p/mu7gqya/)が詳しいです。ここでは簡単な概要のみ記載します。

1. [Twitchのアカウント登録](https://www.twitch.tv/)を行う
2. [Twitchの2段階認証](https://www.twitch.tv/settings/security)を設定する
3. [Twitch developers コンソール](https://dev.twitch.tv/console)にサインインする
4. [アプリケーションを登録](https://dev.twitch.tv/console/apps/)し、クライアントIDとシークレットを発行する
5. アクセストークンを発行する

   ```sh
   curl -i -X POST \
   -d '' \
   'https://id.twitch.tv/oauth2/token?client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&client_secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&grant_type=client_credentials'
   ```

   レスポンス例：

   ```json
   {
     "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
     "expires_in": 5665504,
     "token_type": "bearer"
   }
   ```

6. 発行されたアクセストークンでAPIを叩く

   ```sh
   curl -i -X POST \
   -H "Content-Type:text/plain" \
   -H "Client-ID:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
   -H "Accept:application/json" \
   -H "Authorization:Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
   -d \
   'search "スーパーマリオ";
   limit 10;' \
   'https://api.igdb.com/v4/games'
   ```

   レスポンス例：

   ```json
   [
     {
       "id": 138227
     },
     {
       "id": 229339
     },
     ...
   ]
   ```

   ※デフォルトだとIDだけが返されます

## 使い方の補足

基本的にはAPI仕様書を参考にすれば欲しい情報を取得できますが、探すのに時間がかかったり、仕様書だけではわかりにくい点もあります。以下でそれらを補足します。

### 日本版のゲームタイトル・ゲーム画像を取得する方法

データが存在する場合、関連テーブルである`game_localizations`を取得することで日本語のタイトルや画像を取得できます。

```sh
curl -i -X POST \
-H "Content-Type:text/plain" \
-H "Client-ID:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Accept:application/json" \
-H "Authorization:Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d \
'search "ゼルダの伝説 ブレス オブ ザ ワイルド";
fields name, game_localizations.region,game_localizations.cover.image_id,game_localizations.name;
limit 10;' \
'https://api.igdb.com/v4/games'
```

レスポンス例：

```json
[
  {
    "id": 7346,
    "cover": {
      "id": 172453,
      "image_id": "co3p2d"
    },
    "name": "The Legend of Zelda: Breath of the Wild",
    "game_localizations": [
      {
        "id": 574,
        "name": "ゼルダの伝説 ブレス オブ ザ ワイルド",
        "cover": {
          "id": 275750,
          "image_id": "co5wrq"
        },
        "region": 3
      },
      {
        "id": 575,
        "cover": {
          "id": 239651,
          "image_id": "co54wz"
        },
        "region": 4
      },
      {
        "id": 937,
        "name": "젤다의 전설 브레스 오브 더 와일드",
        "region": 2
      }
    ]
  },
  {...}
]
```

`region = 3`が日本なので、それを抽出して使用します。


```javascriptの場合の例.js
const japaneseLocalization = data.game_localizations?.find((loc) => loc.region === 3);

const japaneseTitle = japaneseLocalization?.name || null;

const japaneseCoverId = japaneseLocalization?.cover?.image_id || null;
const japaneseCoverUrl = `https://images.igdb.com/igdb/image/upload/t_cover_big/${japaneseCoverId}.jpg`
```


### MODやDLC（Downloadコンテンツ）、限定版などを除外する方法

#### 結論

以下の絞り込みを利用すると便利です。
※カテゴリは、用途に依って後述の情報を元に使い分けてください。

```
where category = (0,2,4,8,9,10,11) & version_parent = null;
```

```sh
curl -i -X POST \
-H "Content-Type:text/plain" \
-H "Client-ID:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Accept:application/json" \
-H "Authorization:Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d \
'search "スーパーマリオ";
fields *;
where category = (0,2,4,8,9,10,11) & version_parent = null;
limit 10;' \
'https://api.igdb.com/v4/games'
```

#### 詳細説明

##### MODやDLCを除外する方法

`games.category`で指定します。主要なカテゴリは以下の通りです：

| カテゴリ値 | 名称 | 説明 |
|------------|------|------|
| 0 | main_game | ゲーム本体 |
| 1 | dlc_addon | DLC（追加キャラ、追加スキンなど小規模なもの） |
| 2 | expansion | 大型DLC |
| 3 | bundle | セット品 |
| 4 | standalone_expansion | 単独でプレイ可能な大型拡張パック |
| 5 | mod | ユーザー作成の改造拡張（主にPCゲーム） |
| 6 | episode | エピソード形式で販売されるゲームの各回 |
| 7 | season | FPS、TPSなどでよく見られるアップデートのバージョン |
| 8 | remake | ゲームのリメイク |
| 9 | remaster | ゲームのリマスター作品 |
| 10 | expanded_game | 追加コンテンツ入りの拡張版・完全版 |
| 11 | port | 別ハードでの発売バージョン |
| 12 | fork | 主にPCゲームでforkして開発されたもの |
| 13 | pack | 拡張コンテンツ（DLCに近い小規模な拡張パック） |
| 14 | update | 無料アップデートが含まれてリリースされたバージョン |

<details>
<summary>カテゴリ詳細（クリックで展開）</summary>

- **dlc_addon (1)**: 
  - 説明：追加キャラだったり、追加スキンだったりの小粒な追加コンテンツ。

- **expansion (2)**: 
  - 説明：拡張パック。大型DLC。新たなストーリーだったりで、別途パッケージで販売されるようなもの。プレイするには本編を別途購入する必要があるもの。
  - 例：
    - モンスターハンターライズ サンブレイク
    - ELDENRING SHADOW OF THE ERDTREE
    - スプラトゥーン3 エキスパンションパス

- **bundle (3)**: 
  - 説明：セット品。
  - 例：
    - モンスターハンターライズ ＋ サンブレイク セット
    - ELDEN RING SHADOW OF THE ERDTREE EDITION

- **standalone_expansion (4)**: 
  - 説明：大型拡張パックのうち、拡張パック単体でもプレイ可能なもの。（※最近見ない形態な気がします）
  - 例：
    - 戦国無双 猛将伝

- **season (7)**: 
  - 説明：シーズン。近年のFPS, TPS等で見られる、アップデートのバージョン。
  - 例：
    - APEX シーズン22
    - Fortnite: Chapter 5
    - Splatoon 3: Drizzle Season 2022

- **remake (8)**: 
  - 説明：ゲームのリメイク。（main_gameと同等の立ち位置に近いと個人的には思います）
  - 例：
    - ファイナルファンタジーVII リメイク
    - バイオハザード RE:2 

- **remaster (9)**: 
  - 説明：ゲームのリマスター作品。
  - 例：
    - The Last of Us Remastered
    - DARK SOULS REMASTERED

- **expanded_game (10)**: 
  - 説明：追加コンテンツ入の拡張版。完全版と言われることが有るのでそちらのほうが馴染みやすいかもしれません。
  - 例：
    - ポケットモンスター エメラルド
    - ペルソナ 5 ザ・ロイヤル

- **port (11)**: 
  - 説明：別ハードでの発売バージョン。リメイクに近いが、リメイクが後継・上位ハードでの豪華版の方向に対し、一部機能制限だったり、ゲームの内容を変えて横展開されたもの。（ゲーム内容が変わらない単なるマルチプラットフォームの場合は同じmain_gameとして扱われます）
  - 例：
    - Minecraft（Minecraft: Java Editionに対するBedrock版）
    - ファミコン版 Ys（イース）

- **update (14)**: 
  - 説明：無料アップデートが含まれてリリースされたバージョン。
  - 例：
    - SEKIRO: SHADOWS DIE TWICE GAME OF THE YEAR EDITION

</details>


##### 限定版などを除外する方法

`version_parent = null;`を指定します。バージョン違い（限定版、コレクターズエディション、初回特典付きなど）は、通常版/ゲーム本体が`version_parent`として指定されているため、`null`に絞り込むことで除外できます。


### 1回のAPI呼び出しで取得可能な件数

500件まで取得可能です。ただし、レートリミットが秒間4リクエストとのことなので、大量のゲームタイトルを取得する際は注意が必要です。

[公式ドキュメント](https://api-docs.igdb.com/)より引用。

> The default limit is 10. The maximum value you can set for limit is 500.

> There is a rate limit of 4 requests per second.

## 終わりに

IGDB APIは非常に網羅性が高く、インディゲームなども含めて多数のゲームがヒットします。しかし、バージョン違いやmodなども多数ヒットしてしまうため、適切な絞り込みが重要です。

また、海外のサービスであるため、日本のゲームの情報はどうしても限られます。日本でメジャーなゲームであっても、画像が見つからないこともあります。検索も、日本語でもある程度ヒットしますが、精度が安定しない印象があります。

（審査はあるものの）ユーザー投稿型のデータソースであるため、時々誤った情報や重複などが存在します。必要な機能や情報はローカルで補完するなど、特に日本向けサービスであれば一定のカスタマイズが必要かもしれません。

しかし、これらの注意点を踏まえた上で利用すれば、IGDB APIはゲーム関連のサービスを開発する上で非常に有力なツールとなることは間違いありません。

## 紹介
IGDB APIを利用して開発した個人開発のWEBアプリ、『いまゲーム』を運営していますので、よろしければ覗いてみてください。

「ゲームの『いま』と思い出、ゆるくメモ」をコンセプトに、自分が最近プレイしているゲームを画像付きで簡単に共有できるWEBアプリです。登録不要で、一度共有するくらいなら5分で利用できるので、気軽に利用してください。

匿名でフィードバックを送ることもできます。使っていただいたり、フィードバックをいただけたら泣いて喜びます。

https://www.ima-game.com/?dummy

使用技術等詳細は以下記事に記載しています。

https://qiita.com/oka_yu_f/items/bbdc30ccad57530447c1

良ければ[X(Twitter)](https://twitter.com/oka_yu_f)もフォローしてもらえると嬉しいです。

## 参考資料

- [IGDB API Documentation](https://api-docs.igdb.com/)
- [IGDB API でゲーム情報のデータベースにアクセスしてみる｜まくろぐ](https://maku.blog/p/mu7gqya/)