modに近づく!?バイオームの基礎から応用まで#3

 フィーチャーの続きです。ここからはv1.16以降対応なので注意しましょう。

■ 樹木型

 #2では難易度をあげていく形で説明していきましたが、今回もその次だからといってさらに難しいということはないです。鉱石型と植物型の間くらいでしょうか。
 どちらかというと、いろいろ設定項目がありすぎてすべて説明しきる──それぞれどんな値なのかすべて知るほうが大変です。ということで今回はぜんぶ網羅することはなく、どんなプロパティがあるのかだけを紹介して何が変わるかは読者にお任せといった感じがほとんどになるかもしれません。

フィーチャールールはいままでのフィーチャーの説明を見るとすこしわかると思いますが、何型でもだいたいいっしょです。ということでいままでのフィーチャールールのjsonと同じ書き方なんですが、どうもdistributionの値が悪いと全く生成されなくなってしまうので、その部分のお手本をのせておきます。

"distribution": {
  "iterations": "math.clamp(math.trunc(math.ceil((query.noise(math.trunc(variable.originx / 70), math.trunc(variable.originz / 25)) + 0.2) * 25)), 2, 70)",
  "x": {
    "distribution": "uniform",
    "extent": [ 0, 8 ]
  },
  "y": "query.heightmap(variable.worldx, variable.worldz)",
  "z": {
    "distribution": "uniform", 
    "extent": [ 0, 8 ]
  }
}

そしてこっちが本題のjsonです。

{
  "format_version": "1.13.0",
  "minecraft:tree_feature": {
    "description": {
      "identifier": "diamond_tree_feature"
    },
    "trunk": {
      "trunk_height": {
        "range_min": 5,
        "range_max": 8
      },
      "trunk_block": "minecraft:bedrock"
    },
    "canopy": {
      "canopy_offset": {
        "min": -3,
        "max": 0
      },
      "variation_chance": [
        { "numerator": 1, "denominator": 2 },
        { "numerator": 1, "denominator": 2 },
        { "numerator": 1, "denominator": 2 },
        { "numerator": 1, "denominator": 1 }
      ],
      "leaf_block": "minecraft:diamond_ore"
    },
    "base_block": [
      "minecraft:dirt",
      { "name": "minecraft:dirt", "states": { "dirt_type": "coarse" } }
    ],
    "may_grow_on": [
      "minecraft:dirt",
      "minecraft:grass",
      "minecraft:podzol",
      { "name": "minecraft:dirt", "states": { "dirt_type": "coarse" } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 0 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 1 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 2 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 3 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 4 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 5 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 6 } },
      { "name": "minecraft:farmland", "states": { "moisturized_amount": 7 } }
    ],
    "may_replace": [
      "minecraft:air",
      { "name": "minecraft:leaves", "states": { "old_leaf_type": "oak" } },
      { "name": "minecraft:leaves", "states": { "old_leaf_type": "spruce" } },
      { "name": "minecraft:leaves", "states": { "old_leaf_type": "birch" } },
      { "name": "minecraft:leaves", "states": { "old_leaf_type": "jungle" } },
      { "name": "minecraft:leaves2", "states": { "new_leaf_type": "acacia" } },
      { "name": "minecraft:leaves2", "states": { "new_leaf_type": "dark_oak" } }
    ],
    "may_grow_through": [
      "minecraft:dirt",
      "minecraft:grass",
      { "name": "minecraft:dirt", "states": { "dirt_type": "coarse" } }
    ]
  }
}

 これを適用すると下の画像のようなリッチな木が生成されます。
 それぞれの項目が何を表すかは単語の意味でだいたい推測ができますが、思っていたのと違ったりしたことがあったので説明していきます。

■ trunk_height

 木の幹の高さ。range_minが最小値、range_maxが最大値。

■ trunk_block

 幹を構成するブロックのアイデンティファイア

■ canopy_offset

 葉っぱの位置。minからmaxにかけて葉っぱがつきます(もちろん形は自動で決まります)。

■ leaf_block

 葉っぱを構成するブロックのアイデンティファイア

■ base_block

 根本(ねもと)に生成するブロック。木は草ブロックの上に生成されて、そのときに土ブロックに変化していると思ってたんですが、土は最初から生成されたものだったんですね。

■ may_grow_on

 どのブロックの上に生えるか

■ may_replace

 どのブロックに上書きして生成するか。イメージは/fillコマンドのreplace。

■ may_grow_through

 どのブロックなら貫通して生えるか。いまいちmay_replaceとの違いがよくわかりません。


 ざっと説明しましたが、実はまだ隠れている項目たちがたくさん存在します。ちょっとした説明をはさんでそれらを紹介していきます。

 木は、わかるとおり「幹」の部分と「葉」の部分からできています。そして木についていろいろ設定するときにそれらをひとつのグループとしてとらえなくてはならないということを覚えておいてください。これから紹介するプロパティをとりあえず全部書いておこうなんてがむしゃらなことをするともちろん動きません。
 グループとしてとらえるとは、先程のjsonでtrunkとcanopyというオブジェクトをそれぞれひとつのまとまりで見るということです。trunkオブジェクトがまるまる別のオブジェクトに変えられる、canopyオブジェクトがまるまる別のオブジェクトに変えられるということです。説明が難しいですね、何言ってるかわからなかったら「そのままそういうこと」としてふーんと思ってください。本題に戻れば何が言いたかったのか伝わってくると思います。

■幹

 既存の木にも幹のバリエーションがありますね。ということでお手本のjsonではtrunkというオブジェクトだったところがまるまる次のどれかひとつに変えることができます

○アカシア

"acacia_trunk": {
  "trunk_width": 1,
  "trunk_height": { //幹の高さ
    "base": 5, //ベースの高さ
    "intervals": [ 3, 3 ] //ベースに加える高さの範囲
  },
  "trunk_block": { "name": "minecraft:log2", "states": { "new_log_type": "acacia" } }, //幹を構成するブロック
  "trunk_lean": { //幹の傾きについて
    "allow_diagonal_growth": true,
    "lean_height": { //傾き始める高さ
      "range_min": 1,
      "range_max": 5
    },
    "lean_steps": {
      "range_min": 1,
      "range_max": 4
    }
  },
  "branches": { //枝について
    "branch_chance": 100.0, //枝分かれする確率
    "branch_length": { //枝の長さ
      "range_min": 1,
      "range_max": 4
    },
    "branch_position": {
      "range_min": 1,
      "range_max": 3
    },
    "branch_canopy": { //枝につく葉っぱ
      "acacia_canopy": {
        "canopy_size": 2,
        "leaf_block": { "name": "minecraft:leaves2", "states": { "new_leaf_type": "acacia" } },
        "simplify_canopy": true
      }
    }
  }
}

○樫の大木

"fancy_trunk": {
  "trunk_height": { //幹の高さ
    "base": 5, //ベースの高さ
    "variance": 12,
    "scale": 0.618
  },
  "trunk_width": 1, //幹の太さ(3以上はできなかった気がします)
  "trunk_block": { "name": "minecraft:log", "states": {  "old_log_type": "oak" } }, //幹を構成するブロック
  "branches": { //枝について
    "slope": 0.381, //枝の傾き たぶん0が地面と平行、-1から1までの値
    "density": 1.0, //枝の密度
    "min_altitude_factor": 0.2 //枝分かれする最低高度 たぶんてっぺんが1.0の比
  },
  "width_scale": 1.0,
  "foliage_altitude_factor": 0.3 //葉がつく最低高度
}

○倒木

"fallen_trunk": {
  "log_length": { //丸太の長さ
    "range_min": 4,
    "range_max": 7
  },
  "trunk_block": { "name": "minecraft:log", "states": { "old_log_type": "oak" } }, //構成するブロック
  "log_decoration_feature": "minecraft:optional_log_mushrooms_feature", //デコレーションするフィーチャー
  "trunk_decoration": { //デコレーションについて
    "decoration_block": "minecraft:vine", //デコレーションするブロック
    "decoration_chance": 75.0 //デコレーションする量の確率
  }
}

○巨木

"mega_trunk": {
  "trunk_width": 2, //幹の太さ(3以上はできなかった気がします)
  "trunk_height": { //幹の高さ
    "base": 10, //ベースの高さ
    "intervals": [ 3, 20 ] //ベースに加える高さの範囲
  },
  "trunk_block": { "name": "minecraft:log", "states": { "old_log_type": "jungle" } }, //構成するブロック
  "trunk_decoration": { //デコレーションについて
    "decoration_block": "minecraft:vine", //デコレーションするブロック
    "decoration_chance": { //デコレーションする量の確率
      "numerator": 1, //分子
      "denominator": 3 //分母
    }
  },
  "branches": { //枝分かれについて
    "branch_length": 5, //枝の長さ
    "branch_slope": 0.5, //枝の傾き たぶん0が地面と平行、-1から1までの値
    "branch_interval": {
      "range_min": 2,
      "range_max": 6
    },
    "branch_altitude_factor": { //枝分かれする高度 たぶんてっぺんが1.0の比
       "min": 0.5,
       "max": 1.0
    },
    "branch_canopy": { //枝につく葉っぱ
      "mega_canopy": {
        "canopy_height": {
          "range_min": 2,
          "range_max": 4
        },
        "base_radius": 1,
        "simplify_canopy": true,
        "leaf_block": { "name": "minecraft:leaves", "states": { "old_leaf_type": "jungle" } }
      }
    }
  }
}

 これは最初のお手本にもありますが、そこになかったプロパティがあるので再度紹介。

○樫

"trunk": {
  "trunk_height": { //幹の高さ
    "range_min": 4,
    "range_max": 7
  },
  "trunk_block": { "name": "minecraft:log", "states": { "old_log_type": "oak" } }, //構成するブロック
  "trunk_decoration": { //デコレーションについて
    "decoration_chance": 100.0, //デコレーションする量の確率
    "decoration_block": "minecraft:vine" //デコレーションするブロック
    "can_be_submerged": { //どれだけ沈むか
      "max_depth": 1
    }
  }
}

 もう一度言いますが、この幹のグループの中からいずれかひとつだけをjsonに書くことができます。

■ 葉

○トウヒ(クリスマスツリーみたいなやつ)

"spruce_canopy": {
  "lower_offset": { //下部分の葉の位置
    "range_min": 1,
    "range_max": 3
  },
  "upper_offset": { //上部分の葉の位置
    "range_min": 0,
    "range_max": 3
  },
  "max_radius": { //最大半径
    "range_min": 2,
    "range_max": 4
  },
  "leaf_block": { "name": "minecraft:leaves", "states": { "old_leaf_type": "spruce" } } //構成するブロック
}

○アカシア

"acacia_canopy": {
  "canopy_size": 3, //葉の大きさ
  "leaf_block": { "name": "minecraft:leaves2", "states": { "new_leaf_type": "acacia" } } //構成するブロック
}

○黒樫

"roofed_canopy": {
  "canopy_height": 4, //葉っぱの高さ
  "core_width": 2,
  "outer_radius": 2,
  "inner_radius": 3,
  "leaf_block": { "name": "minecraft:leaves2", "states": { "new_leaf_type": "dark_oak" } } //構成するブロック
}

○マツ(木のてっぺんにちょっとしか葉っぱがないやつ)

"pine_canopy": {
  "base_radius": 1, //ベースの半径
  "canopy_height": { //葉っぱの高さ
    "range_min": 3,
    "range_max": 5
  },
  "leaf_block": { "name": "minecraft:leaves", "states": { "old_leaf_type": "spruce" } } //構成するブロック
}

○巨木

"mega_canopy": {
  "canopy_height": 3, //葉っぱの高さ
  "base_radius": 2, //ベースの半径
  "core_width": 2,
  "leaf_block": { "name": "minecraft:leaves", "states": { "old_leaf_type": "jungle" } } //構成するブロック
}

 これも最初のjsonにありますが再び

○樫

"canopy": {
  "canopy_offset": { //葉っぱの位置
    "min": -3,
    "max": 0
  },
  "variation_chance": [
    { "numerator": 1, "denominator": 2 },
    { "numerator": 1, "denominator": 2 },
    { "numerator": 1, "denominator": 2 },
    { "numerator": 1, "denominator": 1 }
  ],
  "min_width": 2, //幅の最小値
  "leaf_block": { "name": "minecraft:leaves", "states": { "old_leaf_type": "oak" } //構成するブロック
  },
  "canopy_decoration": { //デコレーションについて
    "decoration_block": "minecraft:vine", //デコレーションするブロック
    "decoration_chance": { //デコレーションする量の確率
      "numerator": 1, //分子
      "denominator": 4 //分母
    },
    "num_steps": 4,
    "step_direction": "down"
  }
}

 これも同様に、葉のグループのなかでひとつだけjsonに書くことができます。

データ値が0のブロックを指定する場合は、例えば{ "name": "minecraft:leaves", "states": { "old_leaf_type": "oak" }のかたまりすべてを例えばminecraft:stoneのようにまるごと書き換えることができます。
 ほかのデータ値が0でないブロック(色がついた羊毛など)を生成したいという場合は「modに近づく!?カスタムバイオームの基礎から応用まで#4」Sec.3の「ブロックステートでより詳細的にブロックを指定する」を参照してください。

 長々と書くことになってしまいました……やっと樹木型の終わりです。冒頭にも述べたように、全部どんな効能があるのかを調べるのは本当に骨が折れるようなものなのでざっくりとした説明にしました。次のセクションに移るまえに、気になったひともいたかと思うのでおまけとして黒樫の幹のテンプレートをおいておきます。アカシアの太いバージョンだったんですね。

"acacia_trunk": {
  "trunk_width": 2,
  "trunk_height": {
    "base": 6,
    "intervals": [ 3, 2 ]
  },
  "trunk_block": { "name": "minecraft:log2", "states": { "new_log_type": "dark_oak" } },
  "trunk_lean": {
    "allow_diagonal_growth": false,
    "lean_height": {
      "range_min": 0,
      "range_max": 4
    },
    "lean_steps": {
      "range_min": 0,
      "range_max": 3
    } 
  },
  "branches": {
    "branch_chance": {
      "numerator": 1,
      "denominator": 3
    },
    "branch_length": {
      "range_min": 2,
      "range_max": 5
    },
    "branch_position": 1,
    "branch_canopy": {
      "acacia_canopy": {
        "canopy_size": 2,
        "leaf_block": { "name": "minecraft:leaves2", "states": { "new_leaf_type": "dark_oak" } },
        "simplify_canopy": true
      }
    }
  }
}


■ ストラクチャ型

 フィーチャーの真骨頂と言えるでしょうか。いままでストラクチャーを生成するためには、setblockでひとつずつブロックを置くアニコンをもったエンティティをスポーンさせたり、植物型を使って大量のjsonとともに実現したり……やっぱり巨大なストラクチャを作るにはそれに伴って体力が必要でした。
 しかし!ついにこのときが来たのです!ストラクチャブロックから得られるストラクチャデータを用いてそれをフィーチャーとして利用できるようになりました!もうあんな苦労とはオサラバです!
 そしてなにより、ストラクチャデータで生成するので中身の入ったスポナーやチェストが生成できます!これはこの方法じゃないとできないことです。

 ただし、なんとなく察していたでしょう、ストラクチャブロックからストラクチャデータを取得するにはwindows10版でないといけません……
 まあ、windows10版を持っている知り合いに手伝ってもらうなどできますし、それぐらいならsetblockでひとつずつブロックを置いたりブロックの数+αのjsonを作るよりはマシだと思います。(殺到しなければ、大量のデータじゃなければわたしが担ってもいいかもです)

 では、方法の説明です。
 フィーチャールールは毎度おなじみ、どの型でもいっしょです。樹木型と同様にdistributionだけお手本をのせます。

"distribution": {
  "iterations": 10,
  "scatter_chance": {
    "numerator": 1,
    "denominator": 20
  },
  "coordinate_eval_order": "zxy",
  "x": {
    "distribution": "uniform",
    "extent": [ 0, 16 ]
  },
  "y": "query.heightmap(variable.worldx, variable.worldz)",
  "z": {
    "distribution": "uniform",
    "extent": [ 0, 16 ]
  }
}

 これはちょっと多めに生成されます。普通の建物などならiterationsは1がいいでしょう生成率はscatter_chanceで分数で決められます。上が分子、下が分母の項目。分母が大きくなればなるほど珍しくなります(ただの算数)。

 本題のjsonも、樹木型と違ってストラクチャを生成するだけなのでシンプルです。

{
  "format_version": "1.13.0",
  "minecraft:structure_template_feature": {
    "description": {
      "identifier": "test_structure"
    },
    "structure_name": "mystructure:test",
    "adjustment_radius": 3,
    "facing_direction": "random",
    "constraints": {
      "block_intersection": {
        "block_whitelist": [
          "minecraft:grass",
          "minecraft:dirt", 
          "minecraft:stone",
          "minecraft:tallgrass",
          "minecraft:air"
        ]
      }
    }
  }
}

 facing_directionは生成時の向きです。random以外に知らないんですが、たぶんxとzかと。
 block_intersectionは上書きできるブロックです。草ブロックや土がありますが、それを消すと生成時に1ブロックでもそれらのブロックに重なった場合ストラクチャ全体が生成されません
 ストラクチャデータは、ビヘイビアパックのstructuresというフォルダ(マニフェストと同じ層)を作って入れましょう。
 このjsonがお試しできるように、mystructure:testのファイルを置いておきます。


 最後に、毎度おなじみですが、わたしがわからなかった/検証しなかった部分について何かわかったら教えてください!
 これにてフィーチャーの説明/紹介は終わりです。つぎはチェストのルートテーブルが設定できるようになりたいですね~。ここまで出てしまえばもう追加される要素はほとんどなさそうですが、またアップデートで新要素が増え次第 説明/紹介をしていきたいと思います。
 裏話をすると、#4の記事を書いてから#3であるこの記事を書いています。話の繋がりが不自然なところがあったらごめんなさい。

次↓

MinecraftBEアドオン-ヒント倉庫

MimecraftBEのアドオン作りで困ったときにここで解決できるようにと個人によって作られたものです

0コメント

  • 1000 / 1000