Claude Code に、『あつまれ どうぶつの森』がなぜ開けないのかを調べてもらった。Claude Code は自分で HOME に戻り、「すべてのソフト」を最後まで見て、本体設定の「ソフトの詳細管理」に入り、最後にこう教えてくれた。本体には 508 MB の更新データしか残っておらず、ソフト本体がない。だからシステムがゲームカードを挿すよう求めているのだ、と。
そのあいだ、私はコントローラーに触れていない。これをやったのは switch-use という、約 1 MB の Rust 製コマンドラインツールだ。オープンソースである。

Switch にどう接続するか
本体では Atmosphère を動かし、sys-botbase というシステムモジュールを入れておく。sys-botbase は本体上で TCP 6000 ポートを開き、1 行ずつのテキストコマンドを受け取る。ボタン、スティック、タッチ、スクリーンショットだ。switch-use はこのプロトコルのクライアントで、PC と本体が同じ Wi-Fi にいればよい。USB ケーブルも、常駐プロセスもいらない。
curl -fsSL https://raw.githubusercontent.com/leeguooooo/switch-use/main/install.sh | sh
switch-use discover # ローカルネットワークをスキャンし、本体を見つけたらアドレスを記憶する
switch-use status # バッテリー残量、sys-botbase バージョン、実行中のゲーム
Switch にはアクセシビリティツリーがないので、OCR で補う
以前、私は iphone-use を作った。iPhone にはアクセシビリティツリーがあり、各ボタンの文字と座標を直接読める。agent は文字を読めば操作できる。Switch のシステムはこの層を外部に提供しておらず、sys-botbase から得られるのはスクリーンショットだけだ。
そこで switch-use は Mac 上で Apple の Vision フレームワークを使ってスクリーンショットを認識し、各行の文字とその中心点を列挙する。座標はそのままタッチ座標なので、直接タップできる。
$ switch-use elements
[1] 集合啦!动物森友会 (425,64)
[4] 软件信息 (240,192)
[9] 数据管理 (240,351)
[18] 确定 (1085,685)
この上に 3 つのコマンドがある。どれも iphone-use の使い方にならって作ったものだ。
tap データ管理:この文字を見つけてタップする。画面上に同じ名前が複数あれば、候補を出して選ばせる。見つからなければ、最も近い候補をいくつか出す。wait 続けるとpress A see:続ける:ある文字が出るまで待ってから先へ進む。sleep 1.5を決め打ちしなくてよい。--observe:任意の操作の後ろに付ける。操作後に画面が安定するのを待ち、新しい画面の文字をそのまま返す。agent が別途スクリーンリーダーを走らせる手間が 1 回減る。
中国語、日本語、英語を認識できる。ゲーム内のピクセルフォントやカバー画像の認識はかなり悪く、そうした結果には疑問符が付く。
実機で踏んだ落とし穴
HOME ボタンはトグルである。 本体がすでに HOME にいるときにもう一度押すと、実行中のゲームに戻ってしまう。最初の版の home は単純にボタンを押すだけで、テスト中に『魂斗羅』へ切り替えてしまった。今の home はまず OCR で右上に時計があるかを見る。時計は HOME メニューのときだけ表示される。すでに HOME にいれば何も押さない。
画面切り替え中はボタン入力が飲まれる。 DRIGHT*12 でカーソルを「すべてのソフト」へ移そうとしたが、右キーが何回か抜け落ち、A が『タンクバタリアン』の上で押されてしまった。別のゲームがまだ開いており、システムが「実行中のソフトを終了します」という確認を出し、しかもフォーカスがちょうど「終了」に合っていた。

B を押してキャンセルしたので、問題は起きなかった。その後、skill にルールを 1 つ足した。HOME で A を押す前に、まずカーソルがある項目名を読む。名前は選択中の項目の上だけに表示される。合っていれば押す。
読み込み中のくるくるは文字ではない。 初めて「すべてのソフト」に入ったとき、ページは読み込み中でくるくるしていた。前後 2 回の OCR はどちらもタイトルバーしか読まず、--observe は画面が安定したと思って早く返ってしまった。後でピクセル比較を加えた。スクリーンショットを 160×90 のグレースケールの格子に縮小し、前後 2 フレームで変化が 60 を超える格子を数える。本体で測ると、HOME の選択枠の呼吸するような光の効果は最大でも 5 格子しか変わらない。一方、ページ読み込み中は 1 フレームで 1700 格子以上変わる。そこでしきい値を 8 格子にした。今は文字とピクセルの両方が動かなくなって初めて安定とみなす。ずっと動いている画面、たとえばアニメーションや長い読み込みでは、4 秒待ってから返し、出力に「画面はまだ変化中」と明記する。
HOME での最初のタッチは選択するだけ。 一時期、ドックモードではタッチが効かないのだと思っていた。設定アイコンをタップしても開かなかったからだ。実際には、最初の 1 回はカーソルをアイコンへ移すだけで、もう一度タップして初めて開く。ドックモードでも sys-botbase の仮想タッチは同じように使える。今の touch と tap は、タップ後に前後の画面を比較し、何も変わっていなければエラーにする。agent はタップが成功したと勘違いしない。
agent 向け
リポジトリには SKILL.md が同梱されており、操作手順と上記の落とし穴が書かれている。Claude Code ではプラグインとして入れられる。
/plugin marketplace add leeguooooo/plugins
/plugin install switch-use@leeguooooo-plugins
これは use ファミリーにも入っており、use-family を入れると一緒に入る。skill にはいくつかのルールを固定で書いてある。実行中のゲームを中断する前にまず確認すること。ユーザーが明確に求めない限り、システム設定を変えない、データを削除しない、買い物をしないこと。本体を任天堂のサービスへ接続させないこと。本体は仮想システム、つまり emuMMC の中で使い、Atmosphère の hosts で任天堂サーバーをブロックしておくのが望ましい。
自分で遊びたいなら:携帯ゲームパッド
sys-botbase のこのポートは、agent だけが使えるものではない。私は随身手柄(Pocket Gamepad)という Mac アプリも作った。同じ経路を使い、本体の sys-botbase に接続して、Mac のキーボードや余っているスマートフォンを Switch のコントローラーにする。スマートフォン側に何かをインストールする必要はなく、Mac 上の QR コードを読み取れば横画面で遊べる。
友達が来たのに Joy-Con が 1 組しかないとき、3 人目はこれを使う。7 日間は無料で試用でき、その後は US$1.99 の買い切りだ。どう設定するか、ボタンをどう割り当てるかは、Switch 手柄不够用?用 Mac 键盘和手机多开一个手柄に書いてある。
2 つのツールは同時に開ける。sys-botbase は複数の接続を同時に受け付けるので、随身手柄で遊んでいても、agent はいつもどおりスクリーンショットを撮って画面を読める。
まだできないこと
- OCR は macOS でしか使えない。Linux ではボタン、タッチ、スクリーンショットは使えるが、画面読み取りは自分で画像を見る必要がある。
- OCR ではカーソル位置が分からない。Switch の多くのメニューは方向キーで移動し、選択中の項目は文字ではなく高亮枠で示される。カーソルを動かした後は、やはりスクリーンショットを見て確認する必要がある。
- スクリーンショットは遅い。sys-botbase は JPEG を 16 進数で送る。HOME のような画面で約 0.45 秒、「すべてのソフト」のようにカバー画像で画面が埋まるものは 1.4 秒前後かかる。
コードとインストール手順は GitHub にある。MIT または Apache-2.0 のデュアルライセンスだ。

WeChat Pay
Alipay
コメント
コメントは即時公開されますが、ポリシー違反時は非表示になる場合があります。