ルートテーブルをカスタマイズしよう

前回はクラフトレシピを追加してアイテムを「作る」仕組みを学びました。
今回は「もらう」側の仕組み、loot_table(ルートテーブル)に挑戦です。モブを倒したときのドロップや、ブロックを壊したときの収穫物をJSONファイルで自由に変更・追加できます。pool・entry・conditionという3つの構造さえ押さえれば、確率付きドロップも条件付きドロップも思いのままです。

対応バージョン:Java Edition 1.21.11

目次

前提知識

loot_tableとは

loot_tableはMinecraftがアイテムを「抽選」するときに参照するJSONファイルです。モブのドロップ、ブロックの収穫物、チェストの中身、釣りの結果など、あらゆる「アイテムが出る場面」で使われています。Datapackでバニラのloot_tableと同じパスにファイルを置くと、そのドロップを丸ごと置き換えられます。

フォルダ構成

loot_tableファイルは data/<namespace>/loot_table/ に置きます(1.20.5以降は単数形)。バニラのドロップを上書きしたい場合はネームスペースを minecraft にします。オリジナルのloot_tableを作る場合は自分のネームスペースを使います。

my_datapack/
├── pack.mcmeta
└── data/
    ├── minecraft/
    │   └── loot_table/
    │       ├── blocks/
    │       │   └── coal_ore.json       ← 石炭鉱石のドロップを上書き
    │       └── entities/
    │           └── zombie.json         ← ゾンビのドロップを上書き
    └── my_datapack/
        └── loot_table/
            └── custom_chest.json       ← オリジナルのチェスト用テーブル

バニラのloot_tableのパスを確認したいときは、.minecraft/versions/1.21/1.21.jar を解凍して data/minecraft/loot_table/ フォルダを見ると全ファイルが確認できます。

loot_tableの基本構造

loot_tableは大きく3層の入れ子になっています。この構造を頭に入れてからコードを読むと理解が早まります。

loot_tableのpools→entries→conditionsの3層構造を示した図解
  • pools:抽選のグループ。複数のpoolを持てる。各poolで独立した抽選が行われる
  • entries:pool内の候補アイテムリスト。weight(重み)で出やすさを調整する
  • conditions:pool全体やentry単体に条件をつける。条件を満たさないと抽選されない

ステップ1:ブロックのドロップを変更する

石炭鉱石(coal_ore)を壊したとき、石炭の代わりにダイヤモンドが1〜3個出るように変更します。data/minecraft/loot_table/blocks/coal_ore.json を作成します。

{
  "type": "minecraft:block",
  "pools": [
    {
      "rolls": {
        "min": 1,
        "max": 3
      },
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:diamond"
        }
      ]
    }
  ]
}

"type": "minecraft:block" はこのloot_tableがブロック用であることを示します。rolls は1回の収穫で何回抽選するかです。minmax で範囲指定すると毎回ランダムな回数になります。固定にしたい場合は "rolls": 1 と数値で書くだけです。

石炭鉱石を壊したときにダイヤモンドが複数個ドロップしている状態

ステップ2:重み(weight)で確率を調整する

entriesに複数のアイテムを並べ、weight で出やすさの比率を設定します。ゾンビのドロップを変更して、通常ドロップに加えて低確率でダイヤモンドが出るようにします。data/minecraft/loot_table/entities/zombie.json を作成します。

{
  "type": "minecraft:entity",
  "pools": [
    {
      "rolls": 1,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:rotten_flesh",
          "weight": 9
        },
        {
          "type": "minecraft:item",
          "name": "minecraft:diamond",
          "weight": 1
        }
      ]
    }
  ]
}

weight は比率で指定します。腐った肉が9、ダイヤモンドが1なので、ダイヤモンドが出る確率は10分の1(10%)です。weightを省略すると1として扱われます。"type": "minecraft:entity" はモブ用のloot_tableです。

ステップ3:conditionで条件付きドロップを作る

conditionを使うと「プレイヤーが倒したときだけ」「シルクタッチで採掘したときだけ」といった条件を付けられます。ゾンビをプレイヤーが直接倒した場合だけダイヤモンドが出るように絞り込んでみます。

{
  "type": "minecraft:entity",
  "pools": [
    {
      "rolls": 1,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:rotten_flesh",
          "weight": 9
        },
        {
          "type": "minecraft:item",
          "name": "minecraft:diamond",
          "weight": 1,
          "conditions": [
            {
              "condition": "minecraft:killed_by_player"
            }
          ]
        }
      ]
    }
  ]
}

conditions はentry単体にも、pool全体にも設定できます。entry単体に書くと「そのアイテムだけ」に条件が効きます。よく使う条件を以下にまとめます。

  • minecraft:killed_by_player:プレイヤーが直接倒した場合のみ
  • minecraft:random_chance:指定した確率(0.0〜1.0)で通過する。"chance": 0.1 で10%
  • minecraft:match_tool:特定のエンチャントや種類のツールで採掘した場合のみ
  • minecraft:survives_explosion:爆発でブロックが壊れたときにアイテムが消えず残るかを確率判定する(ブロック用loot_tableに必要)

たとえば腐った肉のpoolにも minecraft:survives_explosion を入れておくと、TNTや爆発でブロックが壊れた際の挙動がバニラらしくなります。

ステップ4:functionsでアイテム数を加工する

entryに functions を追加すると、ドロップ数の範囲指定やエンチャントの対応ができます。

{
  "type": "minecraft:empty",
  "pools": [
    {
      "bonus_rolls": 0,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:rotten_flesh",
          "functions": [
            {
              "function": "minecraft:set_enchantments",
              "enchantments": {
                "minecraft:smite": {
                  "min": 0,
                  "max": 2
                }
              }
            },
            {
              "function": "minecraft:set_count",
              "count": {
                "min": 0,
                "max": 2
              }
            }
          ]
        }
      ],
      "rolls": 1
    }
  ]
}

set_count はドロップ個数の範囲を設定します。set_enchantments はエンチャントを追加します。バニラのゾンビも同じ構成でドロップを定義しているので、JAR内のファイルを参考にするのがおすすめです。

動作確認の手順

  1. ファイルを保存して /reload を実行する
  2. 石炭鉱石(coal_ore)をツルハシで壊してダイヤモンドが出るか確認する(シルクタッチは別パスなので通常ツルハシを使う)
  3. ゾンビをスポーンさせて倒し、ドロップを確認する
  4. エラーが出る場合はJSONのネスト(括弧の対応)とプロパティ名のスペルを確認する

よくある落とし穴として、ブロック用loot_tableを entities/ フォルダに置いてしまう(またはその逆)ミスがあります。パスはバニラのJARと完全に一致させる必要があります。

ゾンビを倒したときにダイヤモンドがドロップしている状態のスクリーンショット

まとめ

  • loot_tableはモブ・ブロック・チェストなどあらゆるアイテム抽選に使われるJSONで、data/minecraft/loot_table/ に同名ファイルを置くとバニラのドロップを上書きできる
  • 構造は pools(グループ)→ entries(候補)→ conditions(条件) の3層。poolが複数あれば独立して抽選される
  • weight で各アイテムの出やすさの比率を設定できる。合計weightで割った値が確率になる
  • conditions でプレイヤーキルや特定ツールなどの発動条件を絞れる。entry単体にもpool全体にも適用可能
  • functions でドロップ個数の幅指定やエンチャントの加算など、アイテムの出力内容を細かく制御できる

次の記事「tellrawで見やすいメッセージを表示しよう」では、チャット欄に色や装飾を付けたリッチなメッセージを表示する方法を解説します。

関連ツール

loot_tableの構造が複雑に感じたら、Misode’s Generator(Loot Table)も活用してみましょう。GUIでpoolやentryを追加しながらJSONを確認でき、条件や関数の選択肢も一覧で見られます。recipe同様、仕組みを理解した上で補助的に使うと制作スピードが上がります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次