【マインクラフト（統合版）】ルートテーブル（Loot Table）の書き方まとめ

# はじめに

ルートテーブル（Loot Table）はアイテムのガチャ的要素が非常に強い定義ファイルです。
マインクラフト内ではチェストの中身やドロップアイテムのほか、釣りアイテムなどもガチャ要素として定義できますので、これらを定義するだけでもゲームとして成り立ってしまうような要素です。

ここでは以下のページでご紹介させて頂いたビヘイビアパック内のオリジナルアイテムを例に挙げて進めますので、ルートテーブルの種類よりも書き方に重点を置いて話を進めます。

https://qiita.com/glasses_seven/items/a7d276b44c9437e7b0a4/

https://qiita.com/glasses_seven/items/7a174722c9030e669eac

:::note info
ルートテーブルの記述はJSON形式なのでJSONの仕様を理解している前提で話を進めます。
:::


# 定義ファイルの所在

ビヘイビアパックのルートディレクトリ直下にある`loot_tables`というディレクトリ内に定義します。
例えばバニラのビヘイビアパックの場合は以下の構成になっています。

```text:バニラのビヘイビアパック内のルートテーブルの構成
/<ビヘイビアパックのルート>
    /loot_tables
        /chests
        /dispensers
        /entities
        /equipment
        /gameplay
        /pots
        /spawners
        empty.json
```

これに対して上記のカスタムビヘイビアパックの構成は以下の通り。

```text:カスタムビヘイビアパック内のルートテーブルの構成
/for-family
    /loot_tables
        arrow_explode.json          「はかいの矢」を取得するルートテーブル
        arrow_stand.json            「スタンドの矢」を取得するルートテーブル
        arrow_thunder.json          「いなずまの矢」を取得するルートテーブル
        bow_mine.json               「機雷の弓」を取得するルートテーブル
        bow_stand.json              「スタンドの弓」を取得するルートテーブル
        bow_thunder.json            「いなずまの弓」を取得するルートテーブル
        explode_sword.json          「はかいのつるぎ」を取得するルートテーブル
        floating_feather.json       「浮遊の羽」を取得するルートテーブル
        funnel_unit.json            「ファンネルユニット」を取得するルートテーブル
        hayabusa_sword.json         「はやぶさの剣」を取得するルートテーブル
        hook_shot.json              「フックショットガン」を取得するルートテーブル
        hover_unit.json             「ホバーユニット」を取得するルートテーブル
        immovable_rod.json          「不動の杖」を取得するルートテーブル
        immovable_stone.json        「不動の魔石」を取得するルートテーブル
        iron-fang.json              「エヴォーカーファングの杖」を取得するルートテーブル
        light_sword.json            「光の剣」を取得するルートテーブル
        rifle_cannon.json           「ライフルキャノン」を取得するルートテーブル
        sweep_rod.json              「スウィープロッド」を取得するルートテーブル
        teleport_rod.json           「瞬間移動の杖」を取得するルートテーブル
        thunder_rod.json            「いかずちの杖」を取得するルートテーブル
        thunder_stone.json          「召雷の魔石」を取得するルートテーブル
        thunder_sword.json          「いなずまの剣」を取得するルートテーブル
        thunder_sword_revised.json  「いなずまの剣改」を取得するルートテーブル
        wind_control_rod.json       「繰風弾の杖」を取得するルートテーブル
        wind_rod.json               「風の杖」を取得するルートテーブル
        wind_rod_revised.json       「暴風の杖」を取得するルートテーブル
```

ご覧のように全て`loot_tables`直下に格納しています。
基本的には`loot_tables`配下であればどのような構成でも構わないのですが、コマンド入力でアイテムを取得する場合は定義ファイルのパスを明記しないといけないので、コマンド行が短くて済むように配慮しています。

また、マインクラフト画面内のビヘイビアパックの一覧のうち一番下のパックから上に向けて上書きされていくという特徴がある為（以下の画面右上の「使用中」の項目）、オリジナルアイテムを作る場合はバニラやそれ以外のビヘイビアパックの定義ファイルと被らないように配慮する必要がある事も忘れてはいけません。

![適用確認](https://socket-manager.github.io/document/minecraft-contents/img/behavior/edit_world_setting_behavior6.png "適用確認")


# 定義ファイルの内容

例えば「いなずまの弓」の場合は以下の内容になっています。

```json:「いなずまの弓」のルートテーブル
{
    "pools": [
        {
            "rolls": 1,
            "entries": [
                {
                    "type": "item",
                    "name": "minecraft:bow",
                    "weight": 1,
                    "functions": [
                        {
                            "function": "set_data",
                            "data": 401
                        },
                        {
                            "function": "set_damage",
                            "damage": 1.0
                        },
                        {
                            "function": "set_name",
                            "name": "いなずまの弓"
                        },
                        {
                            "function": "set_lore",
                            "lore": [
                                "矢を放った方向に稲妻を落とす"
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}
```

オリジナルアイテムを作成する場合、上記の`pools`、`rolls`、`entries`の部分は固定だとお考えください。

`rolls`の項目は抽選回数を指定するところですが、アイテムを取得するのに抽選回数を指定する必要はありませんので固定で１としています。
`entries`の項目には複数のアイテムを指定できますが、決まったアイテムを取得するのに複数のアイテムを指定する必要はありません。

以下は項目の説明です。
<dl>
    <dt>・type</dt>
    <dd>"item"の他に"loot_table"を指定できますが、決まったアイテムを取得するのに他のルートテーブルを参照する必要はありません。</dd>
    <dt>・name</dt>
    <dd>取得したいアイテムのマインクラフトIDを指定します。</dd>
    <dt>・weight</dt>
    <dd>取得するアイテムの抽選確率を指定します。確率といっても百分率ではなく重みを指定するタイプなので正の整数であれば何でも構いません。指定がなくてもデフォルトが１で設定されます。</dd>
    <dt>・functions</dt>
    <dd>アイテムに関する関数を指定します。アイテム属性や個数等の指定ができます。関数の詳細は以下の項目をご覧ください。</dd>
</dl>


# 関数の種類

### set_data

アイテムのデータ値を設定します。
例えば特定の色のポーションなどを指定する時に使用されるようですが、任意の値を割り当ててユニークなアイテムとする事もできます。
本環境ではこの値を使ってユニークアイテムを判定しています（但し全てのアイテムが指定できるわけではないので注意が必要）。

<dl>
    <dt>・コマンドで使用する場合</dt>
    <dd>ターゲットセレクタ内の"hasitem"項目の"data"属性に指定する事で参照できます。</dd>
    <dt>・Websocketサーバーで使用する場合</dt>
    <dd>イベントデータ内のaux値で参照できます。</dd>
</dl>

:::note info
イベントデータの詳細については以下のページをご覧ください。
:::

https://qiita.com/glasses_seven/items/f56d0388dab0de30bf3a/

### set_damage

アイテムの耐久値を設定します。
`set_data`関数を使う場合、たまに耐久値と誤認してマインクラフト内で不具合が発生する事があるのでフェイルセーフとして設定しておくのがお勧めです。


### set_name

以下赤枠部分のアイテム名を設定します。
![アイテム名](https://socket-manager.github.io/document/minecraft-contents/img/loot-table/bow_thunder_label_name.png "アイテム名")


### set_lore

以下赤枠部分のアイテムの説明を設定します。
![アイテム説明](https://socket-manager.github.io/document/minecraft-contents/img/loot-table/bow_thunder_label_lore.png "アイテム説明")


### specific_enchants

エンチャントのリストを設定できます。この方法により、通常はゲーム内でエンチャントできないアイテムにエンチャントを適用できます。

```json:リストの定義パターン
"functions": [
    {
        "function": "specific_enchants",
        "enchants": [
            "knockback",
            "fire_aspect"
        ]
    }
]
```

以下のようにエンチャントをオブジェクトとして定義することにより、エンチャントレベルも定義できます。

```json:オブジェクトの定義パターン
"functions": [
    {
        "function": "specific_enchants",
        "enchants": [
            {
                "id": "knockback",
                "level": 1
            },
            {
                "id": "unbreaking",
                "level": 3
            }
        ]
    }
]
```

以下は属性値。

<dl>
    <dt>id</dt>
    <dd>エンチャントID名</dd>
    <dt>level</dt>
    <dd>エンチャントレベル</dd>
</dl>

:::note warn
最大エンチャントレベルはハードコーディングされています。最大値を超える値を指定するとエンチャントそのものが無効化されるので注意が必要です。
:::

### enchant_with_levels

エンチャントテーブルを通じてエンチャントされたかのようにランダムに抽出されたエンチャントが付与されます。複数付与される事もあります。
以下は属性値。

<dl>
    <dt>levels</dt>
    <dd>ここで定義されたXPレベルを使用してエンチャントを付与します。levels属性内で<code>min</code>と<code>max</code>の属性を使って最小値・最大値を定義する事もできます。</dd>
    <dt>treasure</dt>
    <dd>trueの場合はトレジャーエンチャントを使用可能にします。例えば氷渡り、修繕、魂の速度、束縛の呪い、消滅の呪いなどがあります。</dd>
</dl>

使用例は以下ページ内の「treasure.jsonの定義」の項目をご覧ください。

https://qiita.com/glasses_seven/items/5af11b4a4766af93ea37/


# おわりに

Java版とは異なり統合版ではNBTが使えないという制限があるので注意が必要です。
ルートテーブルの設定項目や関数の種類は他にもたくさんありますので今後必要に応じて追記していく予定です。

Websocketサーバーで受信できるイベントデータや、ルートテーブルに登録されたアイテムを取得するためのコマンドの使い方については、以下のサイトの各コンテンツページに掲載していますので合わせてご覧ください。

https://socket-manager.github.io/document/minecraft-contents/