マルチプレイなら『シン・VPS』がおすすめ!

【マイクラ】apply_bonusでドロップ数を操作する【item_modifier】

【マイクラ】apply_bonusでドロップ数を操作する【item_modifier】

この記事では、Minecraft Java Edition(バージョン1.20.4)の情報をもとに執筆しています。
そのほかのバージョンや機種などでの動作は保証できません。

こんにちは!
マインクラフターのなつめです。

なつめ

2016年からマイクラを楽しんでおり、最近はクリエイティブモードでコマンドを駆使して遊んでいます!

この記事では、こんな疑問を解決します!

本記事の内容
  • apply_bonusでブロック破壊時のドロップ数を操作する
  • 実例

apply_bonusは指定したエンチャントのレベルに応じて、ブロック破壊時のドロップ数を決めることになる項目です。

項目によっては複雑な計算を行う必要がありますが、その分不自然でない乱数を扱うことが出来るので勉強する価値はあります。

計算方法についても詳しく説明しているため、ぜひ参考にしてくださいね。

それでは、さっそく見ていきましょう!

本記事で紹介するデータパックのサンプルはGitHubにてダウンロードできます。

apply_bonusでブロック破壊時のドロップ数を操作する

apply_bonusを指示することで、ブロック破壊時のドロップ数を操作することが出来ます。

具体的には、ブロック破壊時に使用したアイテムに付与されている特定のエンチャントのレベルを参照したうえで、指定した計算式に則ってドロップ数を割り出します。

デフォルトでは幸運のエンチャントがそれに当てはまりますね。

計算式は3種類あり、それぞれの詳しい計算方法については、次項である「実例」やGitHubのREADMEに記載しています。
ここでは大まかな説明だけします。

計算式の指定(fomula)使用する主な計算式
minecraft:binomial_with_bonus_count二項分布をもとに算出する。
minecraft:uniform_bonus_count均一分布(一様分布)をもとに算出する。
minecraft:ore_dropsマイクラ独自の関数を用いる。

また、指示したfomulaによって必須項目が異なります。

binomial_with_bonus_countの場合は、extraとprobabilityの記述が必須となり、前者は整数、後者は0~1の間の値を指示することが必要です。

uniform_bonus_countではbonusMultiplierが必要で、ore_dropsでは特別必要な項目はありません。

生成サイトはこちら!

次の項目で、詳しく見ていきます。

実例

ここからは実際の例を見ていきます。

全てフレイムのエンチャントレベルを参照するように指示しており、そのレベルは2とします。

また、ファイル構成は以下の通りです。

  • データパック本体
    • data
      • minecraft
        • loot_tables
          • blocks
            • 各種ブロックのjsonファイル
              (デフォルトのものに上書きする形)
    • pack.mcmeta

ブロックの破壊時に関する項目であるため、基本的には適切にファイル構成(ルートテーブル)を作成し、デフォルトのものに対して上書きする形にしなければなりません。

binomial_with_bonus_count

binomial_with_bonus_countでは、二項分布を用いてドロップ数を割り出します。

計算を行う前に、extraとprobabilityの値を決めましょう。
この値はjsonファイル内で記述するものです。

今回はextraを2、probabilityを0.2とします。

実際のjsonファイルに記述する場合は、以下の通りです。

{
    "type": "minecraft:block",
    "pools": [
      {
        "rolls": 1,
        "entries": [
          {
            "type": "minecraft:item",
            "name": "minecraft:redstone",
            "functions": [
              {
                "function": "minecraft:apply_bonus",
                "enchantment": "minecraft:flame",
                "formula": "minecraft:binomial_with_bonus_count",
                "parameters": {
                  "extra": 2,
                  "probability": 0.2
                }
              }
            ]
          }
        ]
      }
    ]
  }

計算式は以下の通り。

$$ _nC_xp^x(1-p)^{n-x} $$

nはlevel + extraとなっており、エンチャントのレベルとextraの値を足したものになります。
今回はフレイムがレベル2なので、2+2でn=4となります。

pはprobabilityの値そのものです。

また、xは1と仮定します。
本来は成功回数を示す値ですが、binomial_with_bonus_countでは追加で1個ドロップされる確率を算出するという仮定になります。

全体でどのくらいの確率でドロップするのか知りたい方は以下のサイトを利用して求めるのをおすすめします。

というわけで、式に当てはめると以下の通り。

$$ _4C_1\times0.2^1\times0.8^3 $$

これを計算すると、0.4096という値が出てきて、確率に直すと約40%となります。

つまり上記のjsonファイルの記述+フレイムⅡであれば、約40%の確率で+1個のアイテムがドロップします。

総合的なドロップ数は、rollsの値分だけbinomial_with_bonus_countの計算を行い、導き出されたそれらの値すべてとrollsの値そのものを足した数となるようです。
詳しく調べましたが、確信が持てなかったため間違っている可能性があります。

最大ドロップ数になる確率は低く、多くも少なくもない値を期待値にできるため、不自然なドロップをしないのが特徴です。

uniform_bonus_count

uniform_bonus_countでは、均一分布を用いてドロップ数を決めます。

wikiには均一分布と記載がありましたが、一様分布とも言います。

この項目で必要な記述はbonusMultiplierであり、整数を指定すればOKです。

今回はbonusMultiplierを2としましょう。

uniform_bonus_countではエンチャントレベルとbonusMultiplierを掛けた値がドロップの上限となります。

なので、エンチャントレベルが2の場合は2×2となり、4という値が出てきます。
この4が追加ドロップの上限です。

総合したドロップ数は、binomial_with_bonus_countでも紹介したrollsの値を使用した計算方法を活用することで導き出せます。

jsonファイルの記述例としては、以下の通りになります。

{
    "type": "minecraft:block",
    "pools": [
      {
        "rolls": 1,
        "entries": [
          {
            "type": "minecraft:item",
            "name": "minecraft:amethyst_shard",
            "functions": [
              {
                "function": "minecraft:apply_bonus",
                "enchantment": "minecraft:flame",
                "formula": "minecraft:uniform_bonus_count",
                "parameters": {
                  "bonusMultiplier": 2
                }
              }
            ]
          }
        ]
      }
    ]
  }

すべて均一な確率で選ばれるため、レアなドロップ数を表現できないのが難点です。
裏を返せば、どの値も平等に選ばれるので、その点をどう活かすかが重要になります。

ore_drops

ore_dropsではマイクラ独自の計算式を使います。

具体的には以下の通り。

$$ max(1; randomInt[0 .. (Level + 2)]) $$

ore_dropsでは特別指示する値はなく、指示したエンチャントのレベルに2を足します。
エンチャントのレベルが2であれば、2+2で4ですね。

その後、「0~算出した数字」の中から、ランダムに1つの数字が選ばれます。
ただし算出した数字そのものは含まれないため、今回の場合は0~3の間で選出するわけですね。

算出した数字を含まない仕様であるため、そういうものだと割り切りましょう。

ランダムに数字を選出した後は、その数字と1を比べて大きい方が優先されます。

この最終的に優先された数字がドロップ数となります。
ore_dropsではrollsを足すわけではないので、最後に+1されるなどといったことはありません。

0が選ばれた際には、比較した1の方が大きいため必ず1以上の値になります。
「実質2以上の数字は等しい確率で、それに対して1が選ばれる確率は2倍の抽選を行う」といった感じで捉えると分かりやすいですね。

jsonファイルの記述例としては、以下の通り。

{
    "type": "minecraft:block",
    "pools": [
      {
        "rolls": 1,
        "entries": [
          {
            "type": "minecraft:item",
            "name": "minecraft:emerald",
            "functions": [
              {
                "function": "minecraft:apply_bonus",
                "enchantment": "minecraft:flame",
                "formula": "minecraft:ore_drops"
              }
            ]
          }
        ]
      }
    ]
  }

uniform_bonus_countと似た算出方法ですが、幸運のエンチャントの再現などに活かすことができるのが違いと言えます。

まとめ

というわけで、今回のまとめです。

ポイント
  • apply_bonusを使うことで、指定したエンチャントのレベルに応じたドロップ数になる。
  • 算出するための方法は3種類あり、それぞれに異なる特徴がある。

この記事は以上になります。

  • 【まとめ】functionコマンドの基本から応用【マイクラ】
  • 【まとめ】カスタムストラクチャーの実装・カスタム方法【マイクラ】