1.はじめに
この記事は Pokémon Past Generation Advent Calendar 2023 の178日目の記事です。
ポケモンエメラルドにおけるID調整は人力ではかなり難しいです。TIDとSIDを両方調整するとなると、「"さいしょから はじめる"選択から、名前入力開始まで」、「名前入力開始から終了まで」、「名前入力終了からオダマキ博士との会話終了まで」を全て1F単位でフレームを合わせることが前提で、更にOPでAを押すタイミングや、暗転時間のキー入力によって出現するIDがブレるという鬼畜っぷりです。私の知る限り、手動で任意TID&SIDの調整に成功した方はおりません。(TIDだけなら割といます。)
そのため、エメラルドのID調整はGC自動化を使うのが主流です。今まではORCA GC Controller等を使った自動化プログラムが作成されていましたが、今回はNX Macro Controllerを活用した汎用的なID調整自動化プログラムを紹介します。

2.Em ID調整の概要
ID調整を行う理由は、トレーナーIDを「00000」のような美しい数値にすることや、特定の個体を色違いにすることが挙げられます。色違いの条件は、トレーナーID(TID)、裏ID(SID)、ポケモンの性格値(PID)が関係しています。ID調整によって、TIDとSIDを調整することで、狙った性格値のポケモンを色違いにすることができます。この項目では目的の個体を色違いにするためのIDを検索する方法や、ID調整の仕組みなどについて解説します。
目的の個体を色違いにするIDを検索する
ID調整は目標の個体を光らせるために行うとしても、どんなIDにすれば良いのか分からないので、ツールを使って調べる必要があります。今回は例として、臆病5Vのカイオーガを色違いで捕獲するためのIDを検索します。
まずは光らせたい個体を「3genSearch」の「個体逆算」タブで検索します。カイオーガは固定シンボルなので、「固定」にチェックを入れます。また、Emの固定シンボルはMethod1という個体生成パターンでしか出現しないため、「Method1」にチェックを入れます。あとは目的の個体値と性格を入力して、「計算」をクリックすると、条件に一致する個体が出力されます。固定臆病5Vでは7種類の個体が見つかりましたが、今回は最もA個体値が低い31-7-31-31-31-31を色違いにするIDを検索していきます。

IDの検索には「TIDFinder」というツールを使います。TIDFinderに目的のTIDを入力し、PIDには先ほどの検索した個体の性格値(PID)をコピーして貼り付けます。その後、計算をクリックすると、目標個体を色違いにするためのSIDが出力されます。複数出力されますが、どのSIDを使っても光らせることができます。
Frame3はSIDを決定する際の待機時間のため、最も待機時間が短い「Frame3 : 6609F」、「SID : 14633」の設定を使うことにします。これで、TID : 00000で臆病 31-7-31-31-31-31を光らせるためには、SIDを14633にすれば良いということが分かりました。
なお、SIDの横に出力されている「◆」と「☆」は色違いのエフェクトとなりますが、8世代(剣盾)に送った場合ですので、3世代では関係ありません。

野生で出現する個体でも同じやり方でIDを検索することができますが、Emの野生は通常ではMethod2で、PID再計算が極端に少ない(概ね10回未満)個体のみMethod4、先頭をタマゴにすればMethod1となりますので、検索の際には注意して下さい。(長くなるので、ザックリとしか説明しません。)

IDの決定方法について
TID・SIDの決定方法についても簡単に説明します。Emでは「Frame1("さいしょから はじめる"選択から、名前入力開始まで)」と「Frame2(主人公の名前入力開始から終了まで)」によって、おおよそのTIDが決定し、「Frame3(名前入力終了からオダマキ博士との会話終了まで)」によってSIDが決定します。
これらのフレーム設定は、日本版Emであれば「TIDFinder」で検索することができます。ツールの使い方は直感的に理解できると思いますが、開発者である ぼんじり様の記事でも解説されています。
Frame1の開始はこの画面でA押下してから、

この画面でA押下して、名前入力画面に遷移するまでとなります。

Frame2は名前入力画面に入ってから、名前入力が終わるまでとなります。

Frame3は名前入力を抜けてから、この画面でA押下するまでとなります。

TIDを微調整する方法について(重要)
Frame1とFrame2でTIDが決まることが分かりましたが、双方のフレームを合わせれば必ず指定のTIDを引けるという代物ではなく、ツールの出力結果よりも前後したTIDが出現すると思います。TIDはFrame1とFrame2が合っていたとしても、オープニング(以後OP)を抜ける際のタイミングや、ゲーム内の設定、電池の有無、ゲームの言語、Frame1とFrame2の開始時のキー入力などによって微妙に変化します。
自動化プログラムで目的のTIDを引くための流れとしては、「TIDFinderでFrame1とFrame2を検索し、プログラムに入力する」→「OPでの待機時間をランダム生成して、目的のTIDが出現する設定を見つける」というのが基本となります。(海外版の場合はTIDFinderを使えないので、フレーム設定をランダム生成して探す必要があります。)
なお、TID0を引ける設定については、Discordの3世代自動化鯖で集約しております。OP待機時間は各自の環境によって、多少のズレがありますので、前後5F程度に広げて、同じIDを引けているか確認しながら調整すると良いです。

Selectズレについて
他人のFrame設定を使っても、近くのIDを全く引けない場合があります。こちらは「Selectズレ」というものが悪さをしており、主人公の名前を入力する際に特定回数Selectを押下した場合、出現するIDが1948程度ズレる現象です。
TIDFinderで赤字で表示されているフレーム設定は、Selectズレを使用することで目標ID付近が狙えるフレームです。Selectズレによって目標ID付近が狙えるフレームの場合、ツールに表示されている回数分、名前入力画面でキーボード切り替えを行います。そうでないフレームの場合はSelectボタンの押下回数が表示されている回数と一致しないようにします。

3.ID調整自動化プログラム
リセットから「さいしょからはじめる」を選択し、目的のTIDを引くまで、ループする自動化プログラムとなります。
※ NX Macro Controller用の自動化プログラムです。GC(GBA)自動化の導入はこちらの記事を参考にしましょう。JPN、ENG、FRA、ITA、NOE、ESPの全言語に対応しております。
ゲームでの設定
・「はなしの はやさ」を「はやい」にする。
・ ゲームボーイプレイヤーの画面設定を「フル」にする。
NX Macro Controllerでの設定
・「Var Region」に使用言語を入力する。
・「Var TrainerName」に主人公のトレーナーネームを入力する。
・「Var Gender」に主人公の性別を入力する。
・「Var TID」に目的のTIDを入力する。
・「Var Frame1」、「Var Frame2」、「Var Frame3」をそれぞれ目的のIDが出現するフレームを入力する。(少数単位まで指定可能。)
※ 各種フレーム設定は日本版であればTIDFinderで検索して下さい。
初期設定ではFrame1=1676.6F、Frame2=2063.7F、Frame3=6609Fの固定臆病5VA7用のIDの設定にしています。この設定はSelectを5回押下しない限りズレが発生せず、名前入力時間も余裕がありますので、ID0狙いであれば使いまわせると思います。もし余分にSelectボタンを押下したい場合は42行目の「Var SelectPlus」に増やしたい回数を入力すればOKです。

OP待機時間をランダム生成する
OPをA押下で抜けるタイミングで出現するTIDが若干ズレますので、この仕様を活用して目標のTIDを探していきます。OP待機時間をランダム生成するオプションをつけているので、こちらを活用してください。
36行目の 「Var OPRandom」を「True」にすると、5.5秒~12秒までの範囲でOP待機時間をランダムに生成して、ログに記録しますので、 39行目の「Var OPWaitTime」に生成した待機時間を入力します。
例えば、目的のIDが出現した際の待機時間が「9.825秒」だった場合は、「OPWaitTime」を9.825に変更して、「Var OPRandom」を無効にすればOKです。

なお、設定を探す際は回転率を上げるために「Var Frame3」を750(海外版は1050)にしておくと回転率が良くなります。(初期設定では時間がかかりすぎるので。)
Frame1、Frame2をランダムに生成する
日本版であれば「TIDFinder」から各種フレーム設定を検索できますが、海外版の場合、Frame1とFrame2の設定は力技でフレームを探す必要があります。(ほかの方が見つけてくれれば流用できます。)
30行目の 「Var FrameRandom」を「True」にした場合、1800~2300Fの範囲でフレームをランダムに生成し、33行目で設定している 「Var IDToleranceRange」で目標IDからの許容範囲内(初期設定では±50)のIDを引いた場合は、ログ出力&LINE Notifyで通知しますので、このフレーム設定を基に目標IDに近付けていきます。
プログラムの実行
以上の準備ができたら、プログラムを実行して下さい。Frame1とFrame2がズレることが多い場合などはフレームを小数単位で調整するなどして、効率的な設定を見つけてみて下さい。NXのオプションでWebHookのURLを設定していれば、目的のIDを引いた際に通知してくれます。
引いたIDはcsxファイルと同ディレクトリに作られる「Captures」フォルダに保存されます。TID、Frame1、Frame2、OP待機時間がファイル名になります。

4.御三家乱数自動化プログラム
目的のSIDが引けているか調べるには、実際にそのIDで目的のポケモンが色違いになるか乱数調整する必要があります。そのため、御三家乱数用のプログラムも用意しています。
NX Macro Controllerでの設定
・「Var Frame」で目標の待機フレームを入力する。
・「Var Gosanke」で任意の御三家を入力する。
設定ができたら、オダマキ博士の前でレポートを書いてプログラムを実行し、目標の個体が色違いになるか確認します。

目標の個体が色違いにならない場合はどのSIDを引いたか、総当たりして調べる必要があります。例えば、TID0でFrame3が6609Fで引けるSID14633を目標としている場合、前後2F程度で出現するSIDで光る個体を総当たりし、それでも光らない場合は範囲を広げてください。光る個体が見つかった場合は、Frame3を調整して目的のSIDに一致させるよう、再度ID調整を行います。

無事に目標の個体が色違いになれば、SIDの調整も成功です。おめでとうございます

なお、初期設定では固定臆病5VA7用のIDで光る個体が出現する設定となっています。3gensearchを使って、各自で待機時間を調整して下さい。

5.おわりに
NXのプログラムはタイマーの汎用コマンドがありませんが、C#スクリプトを使えば解決できます。プログラミング言語は自分には難しいかなぁと思いましたが、組み始めてみたら意外と何とかなりました。海外版への対応を手伝っていただいた いぶさん、つっかかりさん、Hopeさん、アインズさん、エトさん ありがとうございます。