【Minecraft Fabric】1.16から1.17へ移行するにあたって少し戸惑った話。初心者が移行時に躓くポイントをぶっ壊す！

# 対象者
- IntelliJ IDEAでModdingしている
- FabricのModding初心者
- 対応しているMinecraftのバージョンを1.17にしたい人
    - 1.17対応のModを新規開発したい人はこの記事を読まずにFabricのGitHubに上がっているModサンプルをベースに開発した方が速いです


# 参考

https://fabricmc.net/wiki/tutorial:migratemappings?s%5B%5D=gradlew&s%5B%5D=migrate

https://fabricmc.net/versions.html

# 開発環境について
<details>
<summary>開発環境についてみる</summary><div>
## 1.16での開発環境

|項目                    |内容                             |
|:----------------------|:--------------------------------|
| IDE                   | IntelliJ IDEA Community 2021.1  |
| Yarn mappings         | 1.16.1+build.1                  |
| Fabric loader version | 0.8.8+build.202                 |
| Fabric version        | 0.13.1+build.370-1.16           |

## 1.17での開発環境

|項目                    |内容                             |
|:----------------------|:--------------------------------|
| IDE                   | IntelliJ IDEA Community 2021.1  |
| Yarn mappings         | 1.17+build.9                    |
| Fabric loader version | 0.11.3                          |
| Fabric version        | 0.35.0+1.17                     |
</div></details>

# 移行のためにまずやったこと
まずは移行するために、ブランチをチェックアウトして```gradle.properties```を下記のように編集しました。このファイルはGradleにおける```build.gradle```の```dependencies```タスクが実行されるときなどに読み込まれる値のため、このファイルを変更すればGradleで定義されているFabricに関する依存関係やMinecraft本体のソースコードの難読化解除に利用するマッピングなどが変更出来るので編集しました。
なお、このファイルのテンプレートは[参考](#参考)の2番目のリンクで簡単に作成できますので見てみてください。

```properties:gradle.properties
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G

# Fabric Properties
	# check these on https://fabricmc.net/use
	minecraft_version=1.17
	yarn_mappings=1.17+build.9
	loader_version=0.11.3

# Mod Properties
	mod_version = 1.0
	maven_group = hogehoge
	archives_base_name = hogehoge

# Dependencies
	# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
	fabric_version=0.35.0+1.17
```
※2021/06/14時点　今後マッピングファイルなど更新されると思いますので各自変更してください。

# 躓いたポイント
上記のファイルを編集するだけで1.17の開発環境へ移行できると思っていたのですが、違いました。。。。。。
躓いたポイントとしては下記の通りです。

- ['fabric-loom'プラグインの適用に失敗する](#fabric-loomプラグインの適用に失敗する)
- [JDK16を要求される](#jdk16を要求される)
- [Gradleが動かない](#gradleが動かない)
- [```import net.minecraft.*```が名前解決できない](#import-netminecraftが名前解決できない)

## 'fabric-loom'プラグインの適用に失敗する
このケースでは以下のようなエラーが出ると思います。

```console
org.gradle.api.plugins.InvalidPluginException: An exception occurred applying plugin request [id: 'fabric-loom', version: '0.x-SNAPSHOT']
```
```console
Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin 'fabric-loom'.
```
これは'fabric-loom'プラグインのバージョンとFabricの依存関係のバージョンが適合してない為に出るエラーです。なので```build.gradle```の一番上に記されている```fabric-loom```のバージョンを[参考](#参考)の2番目のリンク一番下に記されている```Loom Version```の推奨バージョンに変更します。

```gradle:build.gradle
plugins {
	id 'fabric-loom' version 'ここを推奨バージョンに変更する'
	id 'maven-publish'
}
```

##　JDK16を要求される
さて```fabric-loom```を推奨バージョンに変更後Gradleを実行しなおすとおそらく下記のようなエラーが出ます。

```console
> Failed to apply plugin 'fabric-loom'.
   > You are using an outdated version of Java (8). Java 16 or higher is required.
     You can change the Java version in the Gradle settings dialog.
```
現在Gradleを実行してるJDKがJava8つまり1.8で```fabric-loom```のプラグインを適用するにはJava 16以上が必要みたいですね。

Minecraft 1.17の情報をあまり追いかけてなかったので知らなかったのですが、どうやら1.17からJDK16になったようです。これに伴い、Modをビルドするときに使うJDKも16にする必要があります。

### IDEAでJDK16を使うように設定
IDEA Community 2021.1ではOpenJDKをダウンロード出来るようになってるので下記の通り出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447593/df10b529-752b-f1e1-f907-89c6a7375d07.png)
「File」の「Project Structure...」を開いて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447593/50843f9b-0e31-2fda-ef61-b523b78a965a.png)
「Project」の「Project SDK」のプルダウンを開いて「Add SDK」で「Download JDK」を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447593/392cb652-e15e-ea44-10a9-b18b3b914fc5.png)
あとはここのウィンドウでJDK16をダウンロードするだけです。

### GradleでビルドするときにJDK16を使ってビルドさせるように設定
GradleでビルドするときのJDKを指定するには```build.gradle```を下記のように書き換えます。

```gradle:build.gradle
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
```
変更前

```gradle:build.gradle
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
```
変更後

これでJDK16でビルドされるようになります。

##　Gradleが動かない
このケースだと下記のようなエラーが出ると思います。

```console
Caused by: org.gradle.api.GradleException: Failed to create Jar file fabric-loom-0.x-SNAPSHOT.jar.
```

```console
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 60
```

これはGradleがJava 16に対応していない為出るエラーです。
そのためGradleをJava 16に対応させる必要があります。Gradleはバージョン7以降からJava 16に対応しているため、Projectフォルダ内のgradleフォルダからwrapperフォルダにある```gradle-wrapper.properties```ファイルの```distributionUrl```を編集して利用するGradleのバージョンを変更します。

```properties:gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
```
変更前

```properties:gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
```
変更後

このようにバージョン7以降を使うように変更します。

##　```import net.minecraft.*```が名前解決できない
名前解決が出来なくなった根本的な原因は未だにわかりませんが、直接的な原因はGradleが持ってきた```net.minecraft.minecraft```のライブラリがうまく読み込まれないのが原因です。
その為ライブラリをうまく読み込ませるために、IntelliJ IDEAの「File」から「Project Structure」をひらいて「Librarys」を開きます。
![Librarys](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447593/907fe552-da81-2512-fe37-c6169fa8c9a5.png)
Librarysを平板直後

ここから```Gradle: net.minecraft.minecraft:1．17-mapped~~~```を探し選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447593/dc21d3fb-54ee-8b1d-2662-2a3ac107f060.png)

このウィンドウで下記の赤く囲ったところを押して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447593/51c7601c-89df-b26c-1029-b8da5676edfe.png)

Classesで選択されている物とおなじjarファイルを選択してOKを押します。
するとSourcesに選択したjarが追加されると思うのでそのままOKを押すと```net.minecraft.*```の名前が解決されるようになります。

1.16のときはこんな面倒な事をしないでも自動でソースコードを適用してくれていたのですが......よくわかりません。

# バージョンアップ時に覚えておくと便利かもな豆知識

## Yarn mappingsを利用した半自動でのバージョンアップ
これは、yarn mappingsに定義されているマッピングがマッピングファイルのバージョンアップで変更された際に半自動で変更点を書き換えたソースコードを作成してくれる物です。

例えば、今回のように1.17のマッピングファイルにバージョンアップする際にはIDEAのターミナルでGradleのタスクを実行することで変更点を書き換えたソースコードを作成してくれます。なお、タスクは```gradle.properties```を書き換える前に実行しなければ意味がありません。

```terminal:gradle
gradlew migrateMappings --mappings "1.17+build.9"
```
このタスクを実行すると```remappedSrc```フォルダに書き換え後のソースコードが作成されています。

ただしこれは見出しにもあるように半自動なので、すべてのソースコードが1.17に対応するように書き換えられる訳ではなく、あくまでもマッピングファイルによって変更された場所だけが変わるので注意が必要です。とはいえ、全部手動で書き換えるよりも楽ができるので便利なのには変わりはありません。

# 最後に
私が躓いたポイントが誰かしらの役に立てば幸いです。