featureとは
まず、ここでいう"feature"とは何でしょうか?
マイクラで世界を探索していると地上には木が生えていたり、川底や沼底に円状に粘土などが見つかったり、溶岩の池が見つかりますよね?地下を探索すれば鉱石などが見つかりますよね?
featureというのは、こういった、「バイオームを装飾するもの」を指します。
ここではfeatureの中身の設定にあたる、configured_featureとそれに「どこにどのように生成するか」を追加したplaced_featureについて説明します。
configured_feature
まず、基本的な書き方は以下のようになります。
{
"type": type,
"config": {
typeに応じて変化
}
type
featureのタイプです。ここに指定するものでconfigの中身が変わります。
また、どこにどのように生成されるかも大体決まることがあります。
config
どのブロックを使うか、サイズはどれくらいか、等featureの構成設定にあたる部分です。
前述のtypeによってはないものもあります。その場合は空欄にします。
typeの一覧
前述の通り、ここによってconfigの項目が変化したり、どのように生成されるかもある程度決まっていきます。
では、どれくらいの種類があるのでしょうか。
以下の通りです。
はい、かなり多いですね!
このうち、以下のものは動作が決まっており、これといって設定できるものがありません。
忘れましょう。
- basalt_pillar
- blue_ice
- bonus_chest
- chorus_plant
- coral_claw
- coral_mushroom
- coral_tree
- desert_well
- end_island
- freeze_top_layer
- glowstone_blob
- ice_spike
- kelp
- monster_room
- no_op
- vines
- void_start_platform
- weeping_vines
これらを除いて、以下のものが残ります。
- bamboo
- basalt_columns
- block_column
- block_pile
- delta_feature
- disk
- dripstone_cluster
- end_gateway
- end_spike
- fill_layer
- flower
- forest_rock
- fossil
- geode
- huge_brown_mushroom
- huge_fungus
- huge_brown_mushroom
- iceberg
- lake
- large_dripstone
- multiface_growth
- nether_forest_vegetation
- netherrack_replace_blob
- no_bonemeal_flower
- ore
- pointed_dripstone
- random_boolean_selector
- random_patch
- random_selector
- replace_single_block
- root_system
- scattered_ore
- sculk_patch
- seagrass
- simple_block
- simple_random_selector
- spring_feature
- tree
- twisting_vines
- underwater_magma
- vegetation_patch
- waterlogged_vegetation_patch
...まだ多いですね。
今回はこの中から使いやすそうだったり、便利なものを紹介します。
configの書き方
設置系
minecraft:simple_block
ブロックを置く。それだけです。
configの書き方は以下の通り。
{
"to_place": {
"Name": ブロックID,
"Properties": {
blockstates
}
}
minecraft:block_column
東西南北上下のどれかの方向にブロックの柱を伸ばすfeatureです。
複数種類のブロックを混ぜることもできます。
後述するrandom_patchと組み合わせればこのようなものを作ることもできます。
configの書き方はこんな感じ。
{
"direction": "east"/"north"/"south"/"west"/"up"/"down",
"allowed_placement": Block predicate,
"prioritize_tip": true/false,
"layers": [
{
height: 整数/Int provider,
provider: Block state provider
}
}
Block predicateとBlock state providerについてはこちらをご覧ください。
direction
ブロックを伸ばす方向です。
east,north,south,west,up,downのどれかを選びます。
allowed_placement
柱を構築するブロックが置かれる条件を指定します。
ここを満たし、かつ、後述するheightに達するまでブロックを置き続けます。
さて、Block predicateという謎の表記がありますね。
これと、layersのproviderについては後程紹介します。
prioritize_tip
先っぽを残すかどうかです。trueかfalseで指定します。
trueにすると先っぽが確実に残るようになります。(多分)
layers
柱の構成です。
リストになっているように、複数指定可能です。その場合は上に書いたものからどんどん積み上がる感じです。
height
最大何ブロック使うかを表します。
前述のallowed_placement
を満たす場合はここに達するまでブロックを生成します。
整数を直接書くか、後述するInt providerを使って指定します。
provider
柱に使うブロックです。
Blockstate providerの書き方は後述します。
minecraft:delta_feature
玄武岩の三角州にあるような、池みたいなやつを生成します。
あちらは溶岩とマグマブロックでできていますが、それ以外で構成することもできます。
設定項目がシンプルで使いやすいです。
configの書き方は以下の通り。
{
"contents": {
"Name": ブロックID,
"Properties": {
blockstates
},
"rim": {
"Name": ブロックID,
"Properties": {
blockstates
},
"size": 整数/Int provider,
"rim_size": 整数/Int provider
}
contents
池の「流体」部分です。玄武岩の三角州のやつで言えば、溶岩の部分です。
rim
池の周りの部分です。玄武岩の三角州のやつでいえば、マグマブロックの部分です。
size
池の「流体」部分のサイズです。
rim_size
池の縁の部分のサイズです。
minecraft:random_patch
別のplaced_featureを呼び出し、指定した範囲にランダムに設置します。
configの書き方は以下の通り。
{
"feature": placed_feature,
"tries": 整数,
"xz_spread": 整数,
"y_spread": 整数
}
fearure
呼び出したいplaced_featureです。worldgen/placed_featureから指定するか、直接書き込みます。
直接書き込む場合は以下のように書きます。
{
"feature": configured_feature,
"placement": [
{
"type": Placement modifierのtype,
typeによって変化
}
]
}
featureでconfigured_featureを指定し、呼び出す際の条件としてplacementを書き込みます。
placementを満たす場所にplaced_featureが呼び出される、というわけです。
placementの書き方については後程。
tries
試行回数です。勿論正の数である必要があります。
省略可能で、その場合はデフォルトの128が適用されます。
xz_spread
横方向の範囲です。勿論正の数である必要があります。
y_spread
上下方向の範囲です。勿論正の数である必要があります。
minecraft:flower
お花。
minecraft:random_patch
と同様に、別のplaced_featureを呼び出します。
minecraft:random_patch
と違う所は、骨粉使用時にこのfeatureが生えてくることです。
configの書き方はminecraft:random_patch
と同じ。
no_bonemeal_flower
これもお花。
こちらは骨粉使用時に生えてきません。
minecraft:random_patch
とほぼ同じです。
configの書き方も同じ。
置換系
minecraft:replace_single_block
ブロックを1つ、別のブロックに置き換えます。
このfeatureはブロック更新を起こさず、本来置けないはずのブロックを置いたり、本来置けない筈のブロック状態のブロックを置いたりすることができます。
例えば、全部falseやnoneの塀系ブロックはsetblockしても即座にブロック状態が変わってしまうのですが、このfeatureであればそれを阻止することができるのです。
書き方は以下の通り。
{
"targets": [
{
"target": Rule test,
"state": {
"Name": ブロックID,
"Properties": {
blockstates
}
},
...
]
}
target
置換対象の条件を指定します。
条件の指定の仕方ですが、これは何故かこれまで書いてきたBlock predicateではありません。ここにおける指定の仕方については、こちらで紹介しているのでそちらをどうぞ。
state
置換先のブロックを指定します。
minecraft:ore
指定したブロックを別のブロックに置換します。名前を見てわかるように鉱石で使われていることが多いです(鉱石以外でも使われています。例えば、花崗岩とか)
configの書き方は以下の通り。
{
"targets": [
{
"target": Rule test,
"state": {
"Name": ブロックID,
"Properties": {
blockstates
}
},
...
],
"size": 整数,
"discard_chance_on_air_exposure": 小数
}
targets
先程のminecraft:replace_single_block
と同じです。
size
鉱脈のサイズです。Wikiによると、以下のように対応しています。
鉱脈size対応表
size | 実際に生成される量の最大値 |
---|---|
0 | 0 |
1 | 0 |
2 | 0 |
3 | 4 |
4 | 5 |
5 | 8 |
6 | 9 |
7 | 10 |
8 | 10 |
9 | 13 |
10 | 16 |
11 | 17 |
12 | 23 |
13 | 24 |
14 | 24 |
15 | 29 |
16 | 32 |
17 | 37 |
18 | 46 |
19 | 52 |
20 | 52 |
21 | 60 |
22 | 68 |
23 | 68 |
24 | 74 |
25 | 82 |
26 | 94 |
27 | 104 |
28 | 106 |
29 | 120 |
30 | 128 |
31 | 135 |
32 | 149 |
33 | 160 |
34 | 180 |
35 | 190 |
36 | 204 |
37 | 212 |
38 | 228 |
39 | 246 |
40 | 262 |
41 | 276 |
42 | 292 |
43 | 308 |
44 | 324 |
45 | 344 |
46 | 360 |
47 | 381 |
48 | 403 |
49 | 429 |
50 | 452 |
51 | 480 |
52 | 500 |
53 | 530 |
54 | 558 |
55 | 594 |
56 | 616 |
57 | 634 |
58 | 664 |
59 | 694 |
60 | 730 |
61 | 760 |
62 | 790 |
63 | 826 |
64 | 864 |
minecraft:scattered_ore
minecraft:ore
と大体同じです。
こちらはやや分散した感じで生成されます。
configの書き方もore
と同じです。
minecraft:disk
円状にブロックを置換します。
川底や沼地の底に見られるアレです。
実はこのfeature、結構有用です。
まあ、configの書き方を見てください。
{
"state_provider": {
"target": Block predicate,
"fallback": Block state provider,
"rules": [
{
"if_true": Block predicate,
"then": Block state provider,
},
...
]
},
"radius": 整数/Int provider,
"half_height": 整数/Int Provider
}
お気づきいただけただろうか。
...え?まだわからない?
rulesの中を見てください。
if_true、thenというのが見えますね。
…そう、このfeature、なんと条件に応じて置換先のブロックを切り替えることができるんです。
所謂条件分岐ですね。
といっても万能ではないのですが…。
target
変化させたい対象の条件です。
ここに指定した条件の中で、後述するrulesの処理が行われます。
rules
どのブロックをどのブロックに変化させるかを表します。
if_true
、then
という気になるものが見えますね。
先述の通り、if-then構文となっており、条件分岐ができます。
さて、書き方ですが
if_trueには変化させたいブロックの条件を指定し、thenには変化先のブロックを指定します。
ところで、ここのどこにもマッチしなかった場合はどうなるのでしょうか?
fallback
その場合は、ここに指定したブロックに置換されます。
radius
置換される横方向の範囲です。0から8まで指定でき、featureの場所を中心として、ここで指定した数広がります。
ここに指定した数値×2+1がfeatureの横方向の大きさとなります。
横方向、ということは…?
half_height
置換される上下方向の範囲です。
実は上下方向にも広げることができるんです。
0から4まで指定でき、featureの場所を中心として、ここで指定した数広がります。
ここに指定した数×2+1がfeatureの上下方向の大きさとなります。
選択系
複数のPlaced featureをランダムで選出します。
こういうのって単純に便利ですよね。バニラでもちょいちょい使われています。
また、「複数の」と言いましたが実は1つだけ指定することもできます。
当然、それしか使われないわけですが、このfeatureはconfiguted featureでありながらPlaced featureを呼び出すため、Placement modifier、即ち条件付きでfeatureを呼び出す、ってことができたりします。
minecraft:random_selector
複数のplaced_featureのうちのどれかがランダムに選ばれます。
書き方は以下のようになります。
{
"features": [
{
"feature": Placed feature,
"chance": 小数
},
...
],
"default": Placed feature
}
features
選出したいPlaced featureのリストです。空欄([])にすることもできます。
featureにworldgen/placed_featureから選ぶか、直接書きます。
chanceは選ばれやすさです。
ところで、ここで何も選ばれなかったらどうなるのでしょうか?
その場合は…
default
こちらを呼び出します。
minecraft:simple_random_selector
random_selectorに似ていますが、こちらは選出率とかはなく、シンプルに同じ確率で選ばれます。
書き方はrandom_selectorからdefaultとchanceを無くした感じです。
minecraft:random_boolean_selector
こちらは、二者択一でplaced featureを選びます。
booleanとありますが、何かをtrue/falseするとかではなく、単純に2つの中からFifty-Fiftyで選ぶ、というだけです。
書き方は以下のようになります。
{
"feature_false": Placed feature,
"feature_true": Placed feature
}
設置・置換系
minecraft:vegetation_patch
指定した範囲を指定したブロックで置き換え、その範囲の上に確率で別のplaced_featureを呼び出します。
そのfeature単体ではできないサイズや場所に呼び出したりとかできて結構便利です。
configの書き方は以下の通り。
{
"surface": "floor"/"ceiling",
"depth": 整数/Int provider,
"vertical_range": 整数,
"extra_bottom_block_chance ": 小数,
"extra_edge_column_chance": 小数,
"vegetation_chance": 小数,
"xz_radius": 整数/Int provider,
"ground_state": Block state provider,
"replaceable": ブロックタグ,
"vegetation_feature": placed_featureのパス
}
surface
置換・呼び出し場所を地面か天井かを選びます。
surfaceとあるように、表面の部分に呼び出します。
地面ならfloor
を、天井ならceiling
を指定します。
depth
下方向への深さです。
vertical_range
上下方向の探索範囲です。この範囲で地面や天井となる表面があればそこを置き換えます。
extra_bottom_block_chance
0.0から1.0まで指定でき、ここに指定した確率で下方向に範囲が延長されます。
この処理は各ブロックごとに行われます。
extraedge_column_chance
0.0から1.0まで指定でき、ここに指定した確率で横方向に範囲が延長されます。
この処理は各ブロックごとに行われます。
vegetation_patch
placed_featureが呼び出される確率です。
各ブロックごとに判定されます。
xz_radius
横方向の大きさです。
四角形の範囲なので、不揃いにしたければextraedge_column_chance
を指定してください。
ground_state
placed_featureを呼び出す範囲の地面または床をここで指定したブロックに置き換えます。
replaceable
置換対象となるブロックをブロックタグで指定します。
この際、頭に#
をつける必要があるので注意してください。
vegetation_feature
呼び出したいplaced_featureを指定します。
waterlogged_vegetation_patch
こちらもvegetation_patchと同様に別のfeatureを呼び出しますが、所々段丘のように浸水している所があります。
configの書き方はvegetation_patchと同じです。
Int providerの書き方
整数を指定する場合、直接書いてもいいのですが、より細かく指定することもできます。例えば、一定の範囲の中からランダムに指定したり、一定の範囲でカンストさせたり…。
書き方はこんな感じ。
{
"type": type,
typeによって変化
}
type
Int providerのタイプです。ここに指定するものによって、後の項目が変化します。
以下のものがあります。
minecraft:constant
一定の整数です。value
が追加されますが、直書きと変わりません。
minecraft:uniform
範囲指定です。どの数が選ばれるかは完全にランダムです。偏りもありません。
追加項目は以下のようになります。
{
"value": {
"min_inclusive": 整数,
"max_inclusive": 整数
}
}
そういえばルートテーブルとかにもminecraft:uniform
ってありましたよね。あれと似たような書き方です。
minecraft:biased_to_bottom
こちらも範囲指定で、形式もuniform
と同じです。
ただし、こちらはmin_inclusive
側が選ばれやすくなります。
minecraft:weighted_list
(範囲指定とかではなく)こちらで数値を複数決めておき、その中からランダムで選ばれます。
書き方は以下の通りで、ルートテーブルに少し似ています。
{
"distribution": [
{
"data": 整数/Int provider,
"weight": 整数
}
]
}
dataで抽選候補となる整数を書きます。書き方はこれまでと同様です。
weightは選ばれやすさです。
minecraft:clamped
別のInt Providerの値の範囲を固定します。すなわち、下限もしくは上限の数値でカンストさせます。フォーマットは以下のようになります。
{
"value": {
"min_inclusive": 整数,
"max_inclusive": 整数,
"source": Int Provider
}
minecraft:clamp_normal
minecraft:clamp
とつくように、数値の範囲を固定するものですが、こちらでは正規分布を用います。フォーマットは以下のようになります。
{
"value": {
"min_inclusive": 整数,
"max_inclusive": 整数,
"normal": 小数,
"deviation": 小数
}
minecraft:uniform
にnormal
とdeviation
がくっついたような感じ。normal
には正規分布の平均値、deviation
には偏差を指定します。
参考画像
coral_claw
coral_tree
coral_mushroom
dripstone_cluster
large_dripstone
Placed feature
先程紹介したConfigured featureはfeatureの「中身」の設定をするものでした。
こちらは、その「中身」に「どこに、どのように、どれくらい生成するのか」等の設定を加えたものになります
この、「どこに、どのように、どれくらい生成するのか」の部分をPlacement modifierといいます。
ここでは、Placed featureの書き方と、Placement modifierを紹介していきたいと思います。
基本的な書き方
{
"feature": configured feature、
"placement": [
{
"type": Placement modifierのタイプ,
typeによって変化
}
]
}
featureにはworldgen/configured_featureから指定するか、直接オブジェクトで書き込みます。
configured_featureはplace featureからデバッグできるし、ぱっと見すっきりするのでまずは前者をおすすめします。
type
Placement modifierのタイプです。以下のものがあり、これに応じてその後の項目が変化します。
生成位置の条件を参照するタイプ
minecraft:biome
バイオームの設定内のみ有効です。生成予定の位置がバイオームに収まっていれば生成し、そうでなければ何も生成しません。Placed featureは時折バイオームからはみ出て生成されることがありますが、これを入れることで絶対にはみ出なくなります。
minecraft:block_predicate_filter
その位置のブロックがどうなっているか等を条件とします。
Block predicateを使います。
minecraft:carving_mask
従来の洞窟(Carver cave)やネザーの洞窟(Nether Cave)、峡谷を全検出し、埋め尽くすように配置されます。
その中で先程のblock_predicate_filterで地面だけ、みたいに絞ることはできます。
step
という項目が追加され、air
かliquid
が指定できます。
air
は普通の洞窟等、liquid
は水中(流体中)の洞窟を表します。
………その筈なんですが現状、どういうわけかliquidがそもそも機能していません。
air一択です。
最新バージョンでも海底に峡谷が生成されることがありますが、全てAIRだったりします。
1.13の海底峡谷の景観好きだったんだけどなあ…。いつの間にcarverから"underwater_canyon"なくなってるしね。
(画像のは再現です)
minecraft:surface_relative_threshold_filter
てっぺん(heightmap)から指定した上下方向の範囲内の場合にconfigured_featureを生成します。
書き方はこんな感じ。
{
"heightmap": heightmap,
"min_inclusive": 整数,
"max_inclusive": 整数
}
minecraft:surface_water_depth_filter
てっぺんからの深さが指定した数以下のときにconfigured_featureを生成します。
深さはmax_water_depth
で整数で指定します。
生成位置をシフトするタイプ
minecraft:height_range
生成する高度の範囲を指定します。
この場合の追加項目はこちら。
{
"height": Height provider
}
...また知らんワードが出てきましたね。これの指定の仕方は、基本的にこんな感じでやります。
{
"absolute": 座標
}
abosluteは絶対座標を指定します。この他にもワールドの一番下からの高さを指定するabove_bottom
や一番上からの高さを指定するbelow_top
というのがあります。
一定の高度を指定するならこれだけでいいのですが、まあ…そういうわけにもいかないですよね!
より詳細に設定する場合はこういう書き方になります。
{
"type": "minecraft:constant"/"minecraft:uniform"/"minecraft:biased_to_bottom"/"minecraft:very_biased_to_bottom"/"minecraft:trapezoid"/"minecraft:weighted_list",
typeによって変化
}
type:minecraft:constantの場合
直接指定するのと変わりません。value
という項目が追加され、そこに先程のような書き方をすることになります。
type:minecraft:uniformの場合
範囲指定です。書き方はこんな感じ。
{
"min_inclusive": Height provider,
"max_inclusive": Height provider
}
type:biased_to_bottom
こちらも範囲指定です。ただし、こちらはmin_inclusive
寄りの値になりがちです。
書き方はこんな感じ。
{
"min_inclusive": Height provider,
"max_inclusive": Height provider,
"inner": 整数
}
inner?知らんな(マジで)
type:very_biased_to_bottom
こちらも範囲指定です。biased_to_bottomよりもmin_inclusive寄りになる?
よく把握してないので検証してみます。
書き方はbiased_to_bottomと同じ
minecraft:trapezoid
trapezoidとは「台形」という意味です。台形や三角形を描くように、指定した高度範囲の最高(低)値から中央値に向かって大きくなっていきます。
…まあ、こんな感じ!この三角形みたいなのがそうです。
書き方はこんな感じ
{
"min_inclusive": Height provider,
"max_inclusive": Height provider,
"plateau": 整数
}
plateau
は中央部分の長さです。ここを0にすると三角形になります。
中央部分はuniformと同じ扱いになります。
minecraft:weighted_list
複数の高度からランダムに選びます。
書き方はこんな感じ。
{
"distribution": [
{
"data": 整数/Height provider,
"weight": 整数
}
]
}
それぞれの項目の意味は…
もうわかるよね?
minecraft:heightmap
その場所の「最も高い場所」にシフトします。
heightmapについても、こちらで説明してますのでそちらをどうぞ。
minecraft:random_offset
生成位置をずらします。
Placed featureは何もしないと北西の角に配置されます。カスタムディメンジョン弄ってて「何か規則的に並んで草」って場面があると思いますが、この仕様の為に起こっているのです。
このmodifierを使用することで疎らな感じにできます。
書き方はこんな感じ。
{
"xz_spread": 整数/Int provider,
"y_spread": 整数/Int provider
}
xz_spread
X軸とZ軸の位置をずらします。-16から16まで指定できます。
X軸とZ軸両方が適用されます。どちらか片方は残念ながらできません。
y_spread
Y軸の位置をずらします。
こちらも-16から16まで指定できます。
ちょっとしたテクニック
実はこのmodifier、ストラクチャーの内部で使うときにかなり有用です。
というのも、通常ジグソーでPlaced featureを指定する場合、ジグソーの直上にしか呼び出せません。
しかし、このmodifierを使うことで、例えばy_spreadを-2にしたりすればジグソーの真下から生成したりできるわけです。
実はこれを指定したblock_columnが私の改造ネザー要塞の要だったりします。
minecraft:in_square
X軸とZ軸を0から15までランダムに生成位置をずらします。
特に追加項目はありません。
実は下記と同じです。
{
"type": "minecraft:random_offset",
"xz_spread": {
"type": "minecraft:uniform",
"value": {
"min_inclusive": 0,
"max_inclusive": 15
}
},
"y_spread": 0
}
minecraft:fixed_placement
ジ・エンドの黒曜石の足場がfeatureになったことにより追加されました。
生成位置の座標を指定します。
絶対座標ではありますが、生成位置をコントロールできるようになりました。
書き方は以下のようになります。
{
"type": "minecraft:fixed_placement",
"positions": [
X座標,
Y座標,
Z座標
]
}
生成位置の条件参照&生成位置をずらすタイプ
minecraft:environment_scan
ブロックの条件をマッチするまで上か下に位置をずらしながら、max_stepsで指定した回数分まで繰り返し参照します。まさにスキャン。
追加項目はこんな感じ。
{
"direction_of_search": "up"/"down",
"max_steps": 整数,
"target_condition": Block predicate,
"allowed_search_condition": Block predicate
}
direction_of_search
スキャンする方向です。上(up
)か下(down
)を指定します。
max_steps
スキャンする回数の最大です。1から32まで指定できます。
target_condition
生成させたい条件です。
allowed_search_condition
任意の項目です。この条件を満たした場合、引き続きスキャンを続行します。
試行回数を変えるタイプ
minecraft:count
試行回数です。
何も指定しなければ1チャンクに1回なのですが、これを指定した場合、1チャンクにその数だけ試行されるようになります。
count
という項目が追加され、Int providerで指定します。
minecraft:count_on_every_layer
基本的にcountと同じですが、こちらは各高度毎に判定されます。
書き方もcountと同じ。
minecraft:noise_based_count
試行回数がノイズ依存になります。
ノイズが正の数であればその数に、負の数になれば0として扱われ、何も生成されません。
書き方はこんな感じ。
{
"noise_factor": double,
"noise_offset": double,
"noise_to_count_ratio": 整数
}
また、計算式はceil((noise(x / noise_factor, z / noise_factor) + noise_offset) * noise_to_count_ratio)
となっているらしいです。
minecraft:noise_threshold_count
こちらもノイズ依存です。
書き方はこんな感じ。
{
"noise_level": double,
"below_noise": 整数,
"above_noise": 整数
}
まず、noise(x / 200, z / 200) < noise_level
を参照します。これがtrueの場合はbelow_noise
で指定した整数が、そうでなかったらabove_noise
で指定した整数が使われます。
minecraft:rarity_filter
count系までは試行回数を増やすものですが、こちらは逆に減らします。
chance
という項目が追加され、試行数が1/chance
になります。