GitHub Copilotをmcfunctionで活用する

この記事はMinecraft Command AdventCalendar2024 20日目の記事です。

https://qiita.com/advent-calendar/2024/mccmd

他の方も色々な内容で書かれているので上のリンクからど～ぞ。

<!--
(注釈とか付ける部分あればつけた方が良いと思われ)
-->

# はじめに
本記事ではGitHub Copilotをマイクラのコマンド(mcfunction)で使う際のちょっとしたコツを実際に使用している動画とともに解説していきます。JAVA版(datapack)想定で解説していますが、BE(behaviorpackなど)でも導入さえできれば使えると思います。
~~自分が使い始めたタイミングはポンコツだったのに、時間を経て進化したのか予想以上に賢くなり内容が薄っぺらくなってる気もしますが温かい目で見守ってください~~

# GitHub Copilotの概要
ざっくり言うとAIの力でコーディングをサポートしてくれます。
そのおかげでコーディングの速度がめちゃめちゃ上がり効率化に繋がります。
また、書いていくうちにコードを書いている人の癖などを分析してくれて、提案するコードの使い方やコメントアウトでの言い回しなんかも真似してくれます。

**ただし2つだけ欠点があります**

**1. 導入コスト**
GitHub Copilotを使うには月10ドル(年100ドルのプランあり)払う必要があります。趣味で触る人が多いあろうマイクラのコマンド用途だけで使うにはちょ～っと高いです。他にプログラム言語を触っていたり、コマンド関連を仕事にしている人であれば払う価値は大いにあると思います。Copilotが得意としているのは他のプログラム言語なのが余計に壁が高いです。
しかしながら、**学生であればGitHub Studentsに登録することでGitHub Copilotを無料**で使うことができます。学生用メールアドレスがあれば基本登録できるはずなので申し込んで活用してみてね。そうでない人も30日の無料トライアルがあります(サブスクなので解約しないと継続され支払われる点については注意)

**2. mcfunctionじゃ使いにくい**
マイクラコマンドの`バージョンが変わると書き方が大きく変わる`と`既存の言語と文法が少し異なる`関係で情報をある程度与えていないとポンコツになります(とはいえ、Github Copilot提供当初と比べると格段にマシになっていますが、、)

## 追記
この記事を公開する前日(12/19)にGithubCopilotが条件付き(プロンプト数の制限あり)ですが無料で使えるようになりました！
GPTのようなチャットベースで会話できるものは[専用のサイト](https://github.com/copilot)があるようです。Visual StudioやVisual Studio Codeで使える拡張機能版(リアルタイムサジェストが使える)も対象みたい?
直近の情報なので詳しくはまとめきれませんでしたが、参考までに。

https://forest.watch.impress.co.jp/docs/news/1648825.html

:::note info
無料で使えるならとりあえず使ってみて考えるのもいかがでしょうか。
:::


# 導入方法
:::note warn
既にVSCode(Spyglassmc導入済み)を使った開発環境が整っている前提で説明します
(この説明は省かせていただきます。ｺﾞﾒﾝﾈ)
:::

まず、VSCodeの拡張機能(四角が重なってるやつ)の検索タブでcopilotと入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630080/e05e1564-55a9-9478-d980-fb400b138ab1.png)

すると画像のように`GitHub Copilot`と`GitHub Copilot Chat`の拡張機能がでてくるのでそれぞれインストールしてください。
機能を使うためにはGitHubのアカウントをVSCode上で連携する必要があるので忘れずに連携してください。

拡張機能が導入できていれば、右下の部分にCopilotのマークが出ていると思います。
もしそこに斜線が入っている場合は拡張機能の設定からワイルドカード(*)の部分がtrueになっているかどうかを確認してください。

# mcfunctionで使うには？ 
データパックを作るときは開発で使用しているバージョンのマイクラのあれこれをAIに教えなければなりません。
バージョンによって構文や記述方式が異なったりする上に、他のプログラム言語と比べて公開されている作品数が少ないため、データベースにそこまで情報量がなく思うような情報を引き出してくれません。
前者はおのもやなのでともかく、後者はGitHub CopilotがGitHub上のpublicリポジトリのコードを参照しているのでGitHubにコードが上がってくればそのうち改善されていくのかなぁ、と思います。
それはさておき、快適に使おうと思うと前段階として何も知らない新人にいろはを教えるような心持ちでコードを書かなければなりません。処理ごとに丁寧なコメントアウトを心がけましょう。結果的に**第三者が見てもわかりやすいコード**につながるので一石二鳥です。
```例.
# タグ、Flyがあるプレイヤーに対しkillする
/kill @e[tag=Fly]

# temp storageに実行者のデータを代入する
/execute store result storage temp: player_data run data get entity @s
```
これらを書いていくと使用しているバージョンのコマンドのいろはをCopilotが理解し始めてきます。
バージョンによる違いが顕著な部分(itemコンポーネント等)だとデータベースにある要素と一致しないためか提案にばらつきがあるので少し大変ですが、、

# 使用例
とはいえ、実際に使用しているシーンを見ないことには魅力も伝わらないものです。
ということで今回はサンプルコードとして2値を加算した時に指定した値をオーバーフローしているかどうかを調べるコマンドを作成します。
乗算/除算もできますが、長くなるので省略します。
今回記載している部分はバージョンアップでほぼ変わっていないscoreboard部分のため、提案の正確さはあくまで参考程度に。

<details><summary>オーバーフローをチェックする方法(解説)</summary>
<br>
(前提として加算する2値はオーバフローしていないものとします)<br>
内部で扱いたい最大値が<code>L</code>だとし、加算したい値をそれぞれ<code>a,b</code>とします。<br>
すると、2値を足した値が最大値を超えない場合は<b>式、</b><code>a + b <= L</code><b>が成り立ちます。</b><br>
この時<code>b</code>を移行し、<code>a <= L - b</code>に式を変形できます。<br>
<b>この式が成り立たない(左辺が右辺より大きい)時、値がオーバーフローしている</b>ということになりますね。<br>
例: <br>
12800と51200を足したときにシステム内最大値65535を超えるかどうか<br>
<code>12800 <= 65535 - 51200</code> = <code>12800 <= 14335</code><br>

<b>この式は成り立っているため</b>12800と51200を足した値(64000)は<b>最大値65535を超えていない。</b><br>
54321と12345を足したときにシステム内最大値65535を超えるかどうか
<code>54321 <= 65535 - 12345</code> = <code>54321 <= 53190</code><br>
<b>この式は成り立っていないため</b>54321と12345を足した値(66666)は<b>最大値65535を超えている。</b><br>
(負の数同士や正の数と負の数との加算、乗算のオーバーフローチェックもこの考え方を応用すれば作れます)<br>
</details>


## 作成中の動画(gif)
:::note warn
下記のコマンドはMinecraft1.21.3で作成しました。
(が、直近で変更入ってない部分を使っているので新しめのバージョンなら動くと思います)
:::

- オーバーフロー計算部1
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630080/aaad74b5-4245-ed53-3854-650a0e22989d.gif" width=90%>

- オーバーフロー計算部2
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630080/3ee19481-70f2-0f8e-dfc3-3ecb5652cf9d.gif" width=90%>

- 返り値処理
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630080/6b5f8044-aa61-6e08-864c-fce13c448c08.gif" width=90%>

## 作成結果
- 最終版(ミスした箇所も修正済み)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630080/bc42e8d1-3186-cc7e-f69c-7d492f1084f2.gif" width=90%>

---

これらの動画を見て分かる通り、提案されるコマンドが正確でない部分も多々ありますが、コマンドを書く上で効率化には繋がりそうということが見て取れたと思います。
これはどの言語に対してもそうなのですが、**一度記載された処理を使い回せる部分**に関しては提案スピードと正確性がとても高いです。
そのため、AIに対し**説明さえすれば仕組みを理解し軌道修正**もしてくれます。GitHub Copilotに関わらずAIを活用するうえで大事になってくる部分ですね。
記載するコマンドの種類によっては思うようなサジェストが出てこないかもしれませんが、根気強くコメントアウトを続けAIが理解できるようなコマンドを作成することが大切です。

<details><summary>他言語で同様の処理を作成した際の挙動</summary>

比較用に、c++で同様のプログラムを作ったverもおいておきます。
メジャーな言語なのもあってそこまで情報量を与えていなくてもかなり正確なコードを提案してくれるのがわかるかと思います。
~~こっちを先に書いたのに、コマンドよりコーディング時間短いの何かがおかしい~~
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630080/aee560f5-c106-3f70-5d50-993204d00470.gif" width=90%>
</details>

# 結論
- お金に余裕がある、ないしは効率化を図りたい、もしくは学生なら使って損はないと思う
無料で気軽に使えるようになったのでとりあえず使ってみて考えるでも可。
- コマンドに限らず、使う際は
  - 丁寧なコメントアウトを心がける
  - 可読性を考えコーディングする
- どのような言語でも類似処理を書く際は提案スピードが早いので活用する
- AIってつえ～(棒)

GitHub Copilot使い始めてからコーディングがめちゃめちゃ楽しくなった、というのを残しこの記事を終わりたいと思います。

よいコマンドライフを！