# Claude Code に Switch を操作してもらった

Claude Code に、『あつまれ どうぶつの森』がなぜ開けないのかを調べてもらった。Claude Code は自分で HOME に戻り、「すべてのソフト」を最後まで見て、{本体設定|ほんたいせってい}の「ソフトの{詳細管理|しょうさいかんり}」に入り、最後にこう教えてくれた。{本体|ほんたい}には 508 MB の{更新データ|こうしんでーた}しか{残|のこ}っておらず、{ソフト本体|そふとほんたい}がない。だからシステムがゲームカードを{挿|さ}すよう求めているのだ、と。

そのあいだ、私はコントローラーに{触|ふ}れていない。これをやったのは [switch-use](https://github.com/leeguooooo/switch-use) という、約 1 MB の Rust 製コマンドラインツールだ。オープンソースである。

![あつ森のデータ管理ページ：本体メモリー 66.6 MB と SD カード 441 MB の更新データだけがあり、合計 508 MB](https://img.leeguoo.com/media/c90e2594-9d60-49ea-be3b-74b8e99af4a7/switch-acnh-data.jpg)

## Switch にどう{接続|せつぞく}するか

{本体|ほんたい}では Atmosphère を動かし、[sys-botbase](https://github.com/olliz0r/sys-botbase) というシステムモジュールを入れておく。sys-botbase は{本体|ほんたい}上で TCP 6000 ポートを開き、1 行ずつのテキストコマンドを受け取る。ボタン、スティック、タッチ、スクリーンショットだ。switch-use はこのプロトコルのクライアントで、PC と{本体|ほんたい}が同じ Wi-Fi にいればよい。USB ケーブルも、{常駐プロセス|じょうちゅうぷろせす}もいらない。

```sh
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](https://github.com/leeguooooo/iphone-use) を作った。iPhone にはアクセシビリティツリーがあり、各ボタンの文字と{座標|ざひょう}を{直接|ちょくせつ}読める。agent は文字を読めば操作できる。Switch のシステムはこの層を外部に{提供|ていきょう}しておらず、sys-botbase から得られるのはスクリーンショットだけだ。

そこで switch-use は Mac 上で Apple の Vision フレームワークを使ってスクリーンショットを{認識|にんしき}し、各行の文字とその{中心点|ちゅうしんてん}を列挙する。{座標|ざひょう}はそのまま{タッチ座標|たっちざひょう}なので、{直接|ちょくせつ}タップできる。

```text
$ 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 が『タンクバタリアン』の上で押されてしまった。別のゲームがまだ開いており、システムが「実行中のソフトを終了します」という{確認|かくにん}を出し、しかもフォーカスがちょうど「終了」に合っていた。

![誤操作後に出たソフト終了ダイアログ。フォーカスは「終了」にある](https://img.leeguoo.com/media/f55b06f0-7dd9-4779-b7ff-1da3d0fa75a1/switch-close-dialog.jpg)

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](https://github.com/leeguooooo/switch-use/blob/main/SKILL.md) が同梱されており、操作手順と上記の落とし穴が書かれている。Claude Code ではプラグインとして入れられる。

```text
/plugin marketplace add leeguooooo/plugins
/plugin install switch-use@leeguooooo-plugins
```

これは [use ファミリー](https://github.com/leeguooooo/plugins)にも入っており、`use-family` を入れると一緒に入る。skill にはいくつかのルールを固定で書いてある。実行中のゲームを中断する前にまず確認すること。ユーザーが明確に求めない限り、{システム設定|しすてむせってい}を変えない、データを{削除|さくじょ}しない、買い物をしないこと。{本体|ほんたい}を任天堂のサービスへ接続させないこと。{本体|ほんたい}は仮想システム、つまり emuMMC の中で使い、Atmosphère の hosts で任天堂サーバーをブロックしておくのが望ましい。

## 自分で遊びたいなら：{携帯ゲームパッド|けいたいげーむぱっど}

sys-botbase のこのポートは、agent だけが使えるものではない。私は[随身手柄（Pocket Gamepad）](https://app.leeguoo.com/pocket-gamepad)という Mac アプリも作った。同じ経路を使い、{本体|ほんたい}の sys-botbase に接続して、Mac のキーボードや余っているスマートフォンを Switch のコントローラーにする。スマートフォン側に何かをインストールする必要はなく、Mac 上の QR コードを読み取れば横画面で遊べる。

友達が来たのに Joy-Con が 1 組しかないとき、3 人目はこれを使う。7 日間は無料で試用でき、その後は US$1.99 の買い切りだ。どう設定するか、ボタンをどう割り当てるかは、[Switch 手柄不够用？用 Mac 键盘和手机多开一个手柄](https://blog.leeguoo.com/ja/posts/switch-extra-controller-keyboard-phone-atmosphere/)に書いてある。

2 つのツールは同時に開ける。sys-botbase は複数の接続を同時に受け付けるので、随身手柄で遊んでいても、agent はいつもどおりスクリーンショットを撮って画面を読める。

## まだできないこと

- OCR は macOS でしか使えない。Linux ではボタン、タッチ、スクリーンショットは使えるが、画面読み取りは自分で画像を見る必要がある。
- OCR ではカーソル位置が分からない。Switch の多くのメニューは方向キーで移動し、選択中の項目は文字ではなく高亮枠で示される。カーソルを動かした後は、やはりスクリーンショットを見て確認する必要がある。
- スクリーンショットは遅い。sys-botbase は JPEG を 16 進数で送る。HOME のような画面で約 0.45 秒、「すべてのソフト」のようにカバー画像で画面が埋まるものは 1.4 秒前後かかる。

コードとインストール手順は [GitHub](https://github.com/leeguooooo/switch-use) にある。MIT または Apache-2.0 のデュアルライセンスだ。
