KotlinでMinecraftのModdingをするための環境構築

#はじめに
私はこの記事がQiitaでの初投稿となります。なにか不備などがあったら遠慮なく指摘してください。
また、私は**Windows10/Java8/IntelliJIDEA**環境下で行なっています。
また、**この記事はIntelliJ IDEA向け**です。**Eclipseはサポートしていません。**
ForgeGradleを使うため、ここに書いてある方法はMC1.7.10以降しか使えません。
MC1.10にてForgeGradleに修正が加えられていますが、Kotlin利用のために改変する分には何の問題もない程度の修正ですので、基本的に修正分は無視で問題ありません。

#そもそもKotlinとは
[Jetbrains社](https://www.jetbrains.com)が開発している、JavaVM言語(JavaVM上で動く言語。JavaもJavaVM言語)。
Null-safeや、Javaとの完全互換をうたっており、JavaとKotlinの相互呼び出しができる。
つまり、**Javaで書かれた関数やクラスは、Kotlinからもつかうことができる**んです。
ある程度使ってmoddingして見た結果、「KotlinつえーwこれもうJavaほとんどいらんやろw」ってなるくらいにはKotlinは魅力的です。
#Kotlinでmoddingをするにあたって
###絶対に必要なもの
Moddingに必要な環境
使用するPCがインターネットに接続していること

##注意
まず、**KotlinでのModdingの情報は皆無と言っていいレベルで無いです。**
それを覚悟して挑戦してください。
~~まぁ私のGitHub見ればある程度はコードがあるんだけど~~
また、開発環境ではない、実機の環境でKotlinを用いたmodを動かすには、Kotlinのライブラリが必要となります。
ModのJarファイルにライブラリを出力時に一緒に出力する方法をこの記事では紹介しますが、KotlinはApacheLicense2.0でライセンスされているので、ライセンスの確認を行っておいてください。
あと、**Moddingの環境構築はここでは紹介しません。**自分でModdingの環境構築ができている前提で話を進めます。

#KotlinでModdingするための環境を整える
##IDEAにおける設定
IDEAでProjectを開いていない画面から、Configure→Pluginsを開きます。
そして、上部の検索窓に"Kotlin"と入力し、IDEA用のKotlinのプラグインがインストールされていることを確認してください。
インストールされている場合、このように表示されているはずです。
インストールされていなかった場合は後述します。
![Imgur](http://i.imgur.com/9GSSI4w.png)
次に、左下のIntall Jetbrains plugin...と書いてあるボタンをクリックして、出てきたウインドウの検索窓に"Kotlin"と入力してください。
先程確認したときに、Kotlinのプラグインがインストールされていなかった場合は、ここでKotlinのプラグインをインストールしてください。
次に、Kotlinのプラグインがインストールされていた人もKAnnotatorというプラグインをインストールしてください。
これを使うと、JavaのライブラリをKotlinから呼び出す際にNull-Safe関連が非情に楽になるます。
詳細は[このブログ](http://clomie.hatenablog.com/entry/2013/12/22/130149)を参照してください。

##build.gradleの書き換え
build.gradleを以下のように書き換えまてください。
なお、**これは1.10.2用**なので、**他のバージョンの場合、minecraftグループ内の変数を各バージョンのものに書き換えてください**

```Groovy:build.gradle
buildscript {
    repositories {
        jcenter()
        maven {
            name = "forge"
            url = "http://files.minecraftforge.net/maven"
        }
    }
    dependencies {
        classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'
        classpath 'org.jetbrains:annotations:13.0'
    }
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: "kotlin"

tasks.withType(Jar) {
    compileJava.options.encoding = 'UTF-8'
    compileJava.options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
sourceCompatibility = targetCompatibility = "1.8"
compileJava {
    sourceCompatibility = targetCompatibility = "1.8"
}
version = "1.0"
group= "yourGroup"
archivesBaseName = "yourModName"

minecraft {
    version = "1.10.2-12.18.2.2099"
    runDir = "run"
    mappings = "snapshot_20161111"
}

configurations {
    embed
    compile.extendsFrom(embed)
}

dependencies {
    embed 'org.jetbrains.kotlin:kotlin-stdlib:0.12.613'
    compile 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'
    embed 'org.jetbrains:annotations:13.0'
}

jar {
    from configurations.embed.collect { it.isDirectory() ? it : zipTree(it) }
}

processResources
{
    // this will ensure that this task is redone when the versions change.
    inputs.property "version", project.version
    inputs.property "mcversion", project.minecraft.version

    // replace stuff in mcmod.info, nothing else
    from(sourceSets.main.resources.srcDirs) {
        include 'mcmod.info'
                
        // replace version and mcversion
        expand 'version':project.version, 'mcversion':project.minecraft.version
    }
        
    // copy everything else, thats not the mcmod.info
    from(sourceSets.main.resources.srcDirs) {
        exclude 'mcmod.info'
    }
}
```

軽く改変について解説しようと思います。
そんなのどうでもいいって人は飛ばして問題ないです。
まず、Kotlin関係を先に説明します。

```Groovy:build.gradle
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'
classpath 'org.jetbrains:annotations:13.0'
```
この二行は、「ビルド時にこの2つのライブラリをDLしてこい」という意味です。
次の

```Groovy:build.gradle
apply plugin: "kotlin"
```
これは、「GradleにKotlinのプラグインを適用する」という意味です。
先程のclasspathも「kotlin-*gradle-plugin*」でしたしね。
少し飛んで、

```Groovy:build.gradle
dependencies {
    embed 'org.jetbrains.kotlin:kotlin-stdlib:0.12.613'
    compile 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'
    embed 'org.jetbrains:annotations:13.0'
}
```
この三行。
これは、「ビルド時にこれらを一緒にコンパイルしろ」という意味です。
これがないと、ビルド時に「Kotlinのライブラリが無い」ってコンパイルエラーが出ます。
これでKotlinに直接関係があるのは終わり。
次にKotlinに直接関係はない部分ですが、これがないとKotlinでのmoddingに支障がでる可能性があるものもあります。
まず、

```Groovy:gradle
tasks.withType(Jar) {
    compileJava.options.encoding = 'UTF-8'
    compileJava.options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
```
これは、「コンパイル時の文字エンコードをUTF-8にして、コマンドライン引数に2つ付け加える」という意味です。
文字エンコードをURF-8は、moddingをしている人なら普段から使ってる人も多いでしょう。
コメントを日本語で書いたりしたらこれは必須になります。
次のコマンドライン引数は好みの問題ですね。
ログに出てくる警告の詳細が気になったので付け加えました。

```Groovy:build.gradle
sourceCompatibility = targetCompatibility = "1.8"
compileJava {
    sourceCompatibility = targetCompatibility = "1.8"
}
```
これに関しては、1.10.2のGradleで"1.6"という内容でありましたね。
もともと若干違うのを使っていたのですが、ForgeGradle式に統一しました。
これは「Java8でコンパイルしろ」って意味です。
つまり、マイクラのmodはJava6でコンパイルされていたという・・・
~~開発者馬鹿なの？Minecraft付属のランタイムももうJava8になってるじゃねぇか~~
Java6なんてなかった、いいね？
次は2つまとめて行きます。

```Groovy:build.gradle
configurations {
    embed
    compile.extendsFrom(embed)
}
```

```Groovy:build.gradle
jar {
    from configurations.embed.collect { it.isDirectory() ? it : zipTree(it) }
}
```

これらは、この2つで「dependenciesの部分でcompileではなくembed指定していたライブラリを出力時に一緒にjarに入れる」という意味になります。
つまり、これをすることで実機環境でもKotlinライブラリがなくなることはないというわけですね。
これ、多分jarに入れるのはKotlinのGradleプラグインでも問題ないのでしょうが、不具合があったら面倒なのでStandardLibrary(stdlib)を使っています。

##KAnnotatorを使う
build.gradleは先程ので終わりなので、build.graldeをIDEAでインポートし、終わるのを待ってください。
なお、この作業はForgeの各バージョンにつき一回やればその後は基本的に流用できます。
**この作業はしなくても構いません。したら便利程度です。**
まず、上部メニューのAnalyzeにAnnotate Jar Filesという項目が追加されているので、それを選択します。
そうすると、新しいウインドウが開き、そのウインドウの上部にライブラリが全て出ているので、その中からforgeSrcを選び、OKを選びます。
すると、確認のダイアログがでるのでそのままOKを押します。
すると処理が始まるので終わるまで待ちましょう。
処理が終われば完了です。
![Imgur](http://i.imgur.com/wyFlYVY.png)
###forgeSrcがなかった場合
上部メニューの、File→Project Structureを選択します。
開いたウインドウの左側から、Modulesを選択。
中央部分から"Project名"_mainを選び、右側からforgeSrcを探し、右クリックしてMove to Project Libraries...を選択し、出てきたダイアログでOKを選択します。
![Imgur](http://i.imgur.com/0btvwZp.png)
その後、OKを押してウインドウを閉じ、先程の作業を行ってください。
forgeSrcが一覧に表示されているはずです。

#終了
お疲れ様です。
これで**環境構築は**終わりになります。
Kotlinでmoddingをする上では、JavaとKotlinの文法の違いなどが壁になると思われますが、そちらはおいおい解説していこうと思います。
~~正直言って環境構築すら自分で調べてできないのなら結構きつい気がする~~
さて、最後にこれまでの環境構築を半分無駄にすることを書かせて終わりにさせてもらいます。
[YukariLib](https://minecraft.curseforge.com/projects/yukarilib)という、**Kotlinで作られたmodのための前提mod**をこの記事を書いている最中に公開しまいた。
これはオープンソースのKotlinで書かれたライブラリで、これを導入して、mod側で指定が行われていればKotlinのSTDLibをmodに入れていなくてもきちんと動作します。
これをProjectのライブラリにして、Forgeのdependencies指定を行っておけば、~~~Gradleを書き換える必要が無い~~~という非情に便利なライブラリです。
2017年9/3追記:IntelliJのkotlinPliginを使うために、embedではなくcompileでKotlinのSTDLibをdependenciesに書いておくことをお勧めします。
また、1.10.2〜において、[Forgelin](https://minecraft.curseforge.com/projects/shadowfacts-forgelin)というmodがあり、こちらはForgeにHookを仕込んでSTDLibを競合しない形で読み込むので、STDLib目的なら自modへのSTDLibの取り込みや、YukariLibの要求よりも優秀と言えます。
なので、こちらを利用することを推奨します。