もちポケ記録

ポケモンで遊んでいます。最近は対戦画面読み上げアプリを開発しています。また、下手の横好きでパーティ構築など書きます。

PokéAPI を使ってポケモンの一覧を作る

ポケモン対戦画面読み上げアプリ「Pokéscreader for SV」の技術解説です。

対戦画面読み上げアプリでは、映像から読み取ったポケモンの名前を読み上げるために、ポケモンやフォルムの名称を参照する必要があります。そのために名称取得用のデータベースを用意しています。

ちょうど年末の大掃除の一環でパソコンを掃除していて、突貫で作ったデータベース作成スクリプトを片付けようと思いました。せっかくなのでソースコードを公開しつつ、技術解説として記事を書こうと思います。

今回はコア技術として PokéAPI というサービスを使用しています。PokéAPI は個人的によく使っており、ポケモンに関連するツールの開発でもよく耳にします。一方で使ってみると苦労することも多く、知人が苦労している様子も度々見かけます。苦労しそうなパターンをできるだけ列挙したつもりですので、PokéAPI を使った開発をされている方にも届けば嬉しいです。

PokéAPI とは

ポケモンのあらゆる情報を取得できる Web API サービスです。オープンソースソフトウェアとして継続的に開発されています。

Web API として手軽に利用できますし*1、データ構造も丁寧に作られていて RESTful API として使いやすいので、私としてはイチオシの情報源です。もちろん、これは有志の開発者によって編纂されたもので、公式データではありません。自己責任で利用することが前提です。

PokéAPI で一覧を作るときの苦労ポイント

PokéAPI は非常によくできているのですが、使ってみると苦労することも多いです。端的にいうと「細かすぎる」ので、自分が取得したい・区別したい情報単位との対応付けに苦労するのです。

早速ですが、PokéAPIポケモンの一覧を作成するときに苦労するポイントを挙げます。

意識の外にあるポケモンやフォルムに左右される

ものすごく細かい情報まで整備されていますので、実際に使ってみると見落としが頻発します。プレイしたことがない世代だと「なにこれ?」というものばかりです。

一例を挙げると、この記事を書いている 2024年12月時点でピカチュウは 17 種類います (性別違いは含まず)。何も見ずに全部列挙できるでしょうか?

未知のものや見落としに遭遇することは仕方がないことです。気合いでなんとかしましょう。

データ構造との対応付けが難しい

詳細は後述しますが、意外と複雑なデータ構造で管理されています。大まかなルールこそあるものの、「なんでここで区別されているの?」と疑問を持つようなケースが頻発します。

ポケモンというゲームの複雑さに由来するものなので、仕方がないことです。気合いでなんとかしましょう。

基本的には英語である

ポケモンは基本的に日本産のゲームではありますが、PokéAPI の開発コミュニティは英語圏なので、資料のほとんどは英語です。

システム開発では「英語しかない」は日常茶飯事なのですが、ポケモン用語まで英語で調べることになるので、ハードルはさらに高くなります。

これも仕方がないことです。気合いでなんとかしましょう。ポケモン英語を学べるのは面白いですけどね。

PokéAPI保有するポケモンのデータ構造

苦労するポイントについてお話ししたところで、PokéAPI をどのように使って一覧を作るか、方針を述べます。

画面読み上げアプリでは、次の 3 つのデータ構造を走査してデータベースを作成しています。多くの用途で、これらを理解することがスタートになると思います。

Pokémon Species

「同じ図鑑番号が割り当てられるポケモン」の集合です。ここは簡単に区別できると思います。

Pokémon

Pokémon Species をさらに細かく分類した構造で、大雑把にいえば「タイプ以外の性能が同じポケモン」の集合です。

ただし、ここからは独特な区別もたくさんあります。こればかりは具体例を挙げていくほかありませんので、私が確認したケースをご紹介します。

性能が決まるので、特性や種族値はこのデータに含まれます。タイプもありますが、このあとに紹介する姿の違いによって変わることがあります。

Pokémon Form

Pokémon Species を姿について分類した構造です。ポケモンの性能に関連するデータでは最も細かい単位です。

読み上げアプリにおける実装例

さて、いよいよ実装の解説です。細かいところは今後変えるかもしれませんので、記事としては大枠だけ解説しようと思います。

GitHub リポジトリ takosavi/pokescreader-databaseソースコードを公開していますので、具体的な実装を知りたい方はソースコードをご覧ください。

処理フロー

画面読み上げでは最低限「姿が違うことで性能の違いを認識できる」ものを区別したいので、Pokémon Form まで参照する必要があります。次の手順でデータを走査していきます。

  1. /pokedex/national全国図鑑を取得する
  2. 図鑑の .pokemon_species フィールドを参照し、Pokémon Species 一覧を取得する
  3. Pokémon Species.varieties.pokemon フィールドを参照し、Pokémon 一覧を取得する
  4. Pokémon.forms フィールドを参照し、Pokémon Form 一覧を取得する

重複・不要な情報を省く

姿と性能に差がない重複、ポケモン SV で登場しないものは適宜省いています。

余計な情報があると、他の情報との紐づけ作業がとても面倒になります。削除できるものは削除しておいたほうが使いやすいデータになります。

良い方法かどうか自信がありませんが、多くは PokémonPokémon Formname の規則で判断できそうでした。いくつか例をご紹介します。

Pokémonname で区別する
Pokémon Formname で区別する
  • ギザみみピチュウ: "-spiky-eared" が含まれる
  • いちごアメざいく以外のマホイップ: "alcremie-" で始まり、かつ "-strawberry-sweet" が含まれない

作成したデータの運用

PokéAPI は継続的に開発されていますので、いつの間にかデータが拡充されたり、細かい挙動が変わったりします。折に触れてデータ更新し、前回作成したデータとの差分を確認し、周辺データを含め更新作業を行います。

まとめ

PokéAPI を用いたポケモンの一覧化について解説しました。具体的な実装は汎用的ではないと思っていますが、処理の流れそのものはよくあるものだと思います。他のポケモン関連ツール開発の参考になれば幸いです。

ここで収集したポケモンの情報は、ポケモン図鑑での情報に近いものです。画面読み上げアプリという文脈では、余計な情報を含んでいるものが多くあります。たとえば、いくら見た目がそうだからといって、選出画面で「ザシアン (れきせんのゆうしゃ)」と読まれるのはちょっと違うわけです。*2

画面読み上げアプリができるだけ自然に情報を伝える工夫については、また別の機会にお話ししたいと思います。

*1:Fair Use Policy は守りましょう。

*2:ちょっと難しい例かもしれないので解説です。選出画面では持ち物に関係なく「れきせんのゆうしゃ」フォルムで表示されます。対戦で場に出た時にはじめて、持ち物に応じて「けんのおう」フォルムに変わります。どのみち選出画面でわかる情報ではないので、選出画面で「れきせんのゆうしゃ」という情報は不要なわけです。