カスタムディメンジョンについて ~ featureを作ろう

# featureとは
まず、ここでいう"feature"とは何でしょうか？
マイクラで世界を探索していると地上には木が生えていたり、川底や沼底に円状に粘土などが見つかったり、溶岩の池が見つかりますよね？地下を探索すれば鉱石などが見つかりますよね？
featureというのは、こういった、「バイオームを装飾するもの」を指します。

ここではfeatureの中身の設定にあたる、**configured_feature**とそれに「どこにどのように生成するか」を追加した**placed_feature**について説明します。

# configured_feature
まず、基本的な書き方は以下のようになります。
```
{
  "type": type,
  "config": {
    typeに応じて変化
}
 ```

 ### type
featureのタイプです。ここに指定するものでconfigの中身が変わります。
また、どこにどのように生成されるかも大体決まることがあります。

### config
どのブロックを使うか、サイズはどれくらいか、等featureの構成設定にあたる部分です。
前述のtypeによってはないものもあります。その場合は空欄にします。

#### typeの一覧
前述の通り、ここによってconfigの項目が変化したり、どのように生成されるかもある程度決まっていきます。

では、どれくらいの種類があるのでしょうか。
以下の通りです。

https://gist.github.com/KKMNNOIR/7f943ebcd5dd0c44b813a8af2a9d70a6
<!--
| type | 説明 |
|:-:|:-:|
| bamboo | 竹。竹林バイオームのポドゾルはこれの1つとして生成されています。 |
| basalt_columns | 玄武岩の三角州にある、柱状節理  |
| basalt_pillar | ソウルサンドの谷で天井から溶岩みたいに垂れてる玄武岩 |
| block_column | ブロックの柱を生成する |
| block_column | 村で見られる、無造作に山積みされたようなブロックの塊を生成します。|
| blue_ice | |
| bonus_chest ||
| chorus_plant |
| coral_claw | |
| coral_mushroom| |
| coral_tree | |
| delta_feature | 玄武岩の三角州にある溶岩の池みたいなやつ |
| desert_well | 砂漠の井戸 |
| disk | 川底や沼地の底に円状に生成される粘土や土や砂とか |
| dripstone_cluster | 大きい方の鍾乳石 |
| end_gateway | |
| end_island | エンドの小島に点在しているやつ |
| end_spike | エンドの中心島の黒曜石の塔 |
| fallen_tree| 倒木。BEには前からあったアレです。|
| fill_layer | 指定した高度の何もない所を埋め尽くす |
| flower | 花。ここで指定したfeatureが骨粉使用時に生えてくる。 |
| forest_rock | タイガの原生林の苔石の岩 |
| fossil | 化石。ストラクチャーデータもプロセッサーも読み込めて、なおかつPlacement modifierが適用されるため、有用だが絶対に地下に埋まるように位置がずれてしまう。 |
| freeze_top_layer | 寒冷バイオームの表面が凍ったり積雪してたりするやつ |
| geode | ジオードです。球状のやつです。アメジストジオードで使われています。アメジスト系、滑らかな玄武岩、方解石以外で構成させることもできます。 |
| glowstone_blob | ネザーの天井にくっついているグロウストーンの塊 |
| huge_brown_mushroom | 茶色い巨大キノコ |
| huge_fungus | 巨大ネザーキノコ |
| huge_brown_mushroom | 赤い巨大キノコ |
| iceberg| 氷山。水上じゃないと生成されない |
| kelp | 昆布 |
| lake | 池 |
| large_dripstone ||
| monster_room | スポナー部屋 |
| multiface_growth | ヒカリゴケやスカルクヴェイン |
| nether_forest_vegetation | |
| netherrack_replace_blob | 玄武岩の三角州の玄武岩やブラックストーンの塊がこれ。netherrack_replaceと言いながらネザーラック以外も置換できる。再帰可能 |
| no_bonemeal_flower| 花と大体同じだが、骨粉使用時に生えてこない |
| no_op | 何もしない、をする |
| ore | 鉱石 |
| pointed_dripstone | 小さい方の鍾乳石 |
| random_boolean_selector | 2つのfeatureのどちらかを1:1で選ぶ。|
| random_patch | 指定したplaced_featureを指定した範囲にランダムで生成させる。|
| random_selector | 複数のfeatureからランダムで選ぶ。 |
| replace_single_block | ブロックを1つ置換する。 |
| root_system | ツツジの木の下から伸びている根っこです。木とセットで生成されています。一見、木の根元から根っこが伸びているように見えますが、実は下から根っことなるブロックに置換され、最上部で木に当たるfeatureを生成しています。|
| scattered_ore | 鉱石と似ていますが、やや分散して生成されます。|
| sculk_patch | スカルク系 |
| seagrass | 海草 |
| simple_block | ブロックを1つ、設置します。|
| simple_random_selector | random_selector同様、複数のfeatureからランダムで選びます。random_selectorは選択を偏らせることができますが、こちらは一様に選ばれます。|
| spring_feature | 洞窟や崖とかから湧き出ている滝みたいな奴です。|
| tree | 木。葉、幹、生えている場所のブロック、根、装飾、生成に必要な空間を設定可能。 |
| twisting_vines | ねじれツタ |
| underwater_magma | 洞窟の帯水層などの水底にマグマブロックが見れることがありますよね？アレです。|
| vegetation_patch | 指定した範囲にランダムにplaced_featureを生成させます。バニラでは繁茂した洞窟にツツジやらなにやら生やすのに使われています。|
| vines | ツタを這わせます。blockstatesはその場所に応じて自動的に変わります。|
| void_start_platform | ワールドタイプ「Void」のあの足場です。|
| waterlogged_vegetation_patch | vegetation_patchと大体同じですが、こちらは時折水溜りが発生します。|
| weeping_vines | 枝垂れツタ |
-->

はい、かなり多いですね！
このうち、以下のものは動作が決まっており、これといって設定できるものがありません。
忘れましょう。

* 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と組み合わせればこのようなものを作ることもできます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/08c9dfbd-f55f-4d98-b108-59b978df8aa5.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/e6862822-00ad-fdaf-d235-396126819a04.png" width="50%">
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については[こちら](https://qiita.com/noir_kokumin/items/e0839404a4383ebce0cf?utm_campaign=post_article&utm_medium=twitter&utm_source=twitter_share&s=09)をご覧ください。

###### 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ではありません。ここにおける指定の仕方については、[こちら](https://note.com/noir_kokumin/n/n99b336fe95fd#0b6c35a0-1fc1-4f60-a82e-a40babe74187)で紹介しているのでそちらをどうぞ。

###### 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](https://minecraft.fandom.com/ja/wiki/%E9%89%B1%E7%9F%B3_(%E7%94%9F%E6%88%90%E7%89%A9)#%E7%94%9F%E6%88%90)によると、以下のように対応しています。<!--ここを転記したものです。wiki見ろでもいいのですが、盥回し感あるし、(特に今の日本語版のアクティブな)編集陣が人として嫌いなので-->
<details>
<summary>鉱脈size対応表</summary>
<table>
 <thead>
    <tr>
      <th>size</th><th>実際に生成される量の最大値</th>
    </tr>
  </thead>
  <tr>
    <td> 0 </td> <td>0</td>
  </tr>
  <tr>
    <td> 1 </td> <td>0</td>
  </tr>
  <tr>
    <td> 2 </td> <td>0</td>
  </tr>
  <tr>
    <td> 3 </td> <td>4</td>
  </tr>
  <tr>
    <td> 4 </td> <td>5</td>
  </tr>
  <tr>
    <td> 5 </td> <td>8</td>
  </tr>
  <tr>
    <td> 6 </td> <td>9</td>
  </tr>
  <tr>
    <td> 7 </td> <td>10</td>
  </tr>
  <tr>
    <td> 8 </td> <td>10</td>
  </tr>
  <tr>
    <td> 9 </td> <td>13</td>
  </tr>
  <tr>
    <td> 10 </td> <td>16</td>
  </tr>
  <tr>
    <td> 11 </td> <td>17</td>
  </tr>
  <tr>
    <td> 12 </td> <td>23</td>
  </tr>
  <tr>
    <td> 13 </td> <td>24</td>
  </tr>
  <tr>
    <td> 14 </td> <td>24</td>
  </tr>
  <tr>
    <td> 15 </td> <td>29</td>
  </tr>
  <tr>
    <td> 16 </td> <td>32</td>
  </tr>
  <tr>
    <td> 17 </td> <td>37</td>
  </tr>
  <tr>
    <td> 18 </td> <td>46</td>
  </tr>
  <tr>
    <td> 19 </td> <td>52</td>
  </tr>
  <tr>
    <td> 20 </td> <td>52</td>
  </tr>
  <tr>
    <td> 21 </td> <td>60</td>
  </tr>
  <tr>
    <td> 22 </td> <td>68</td>
  </tr>
  <tr>
    <td> 23 </td> <td>68</td>
  </tr>
  <tr>
    <td> 24 </td> <td>74</td>
  </tr>
  <tr>
    <td> 25 </td> <td>82</td>
  </tr>
  <tr>
    <td> 26 </td> <td>94</td>
  </tr>
  <tr>
    <td> 27 </td> <td>104</td>
  </tr>
  <tr>
    <td> 28 </td> <td>106</td>
  </tr>
  <tr>
    <td> 29 </td> <td>120</td>
  </tr>
  <tr>
    <td> 30 </td> <td>128</td>
  </tr>
  <tr>
    <td> 31 </td> <td>135</td>
  </tr>
  <tr>
    <td> 32 </td> <td>149</td>
  </tr>
  <tr>
    <td> 33 </td> <td>160</td>
  </tr>
  <tr>
    <td> 34 </td> <td>180</td>
  </tr>
  <tr>
    <td> 35 </td> <td>190</td>
  </tr>
  <tr>
    <td> 36 </td> <td>204</td>
  </tr>
  <tr>
    <td> 37 </td> <td>212</td>
  </tr>
  <tr>
    <td> 38 </td> <td>228</td>
  </tr>
  <tr>
    <td> 39 </td> <td>246</td>
  </tr>
  <tr>
    <td> 40 </td> <td>262</td>
  </tr>
  <tr>
    <td> 41 </td> <td>276</td>
  </tr>
  <tr>
    <td> 42 </td> <td>292</td>
  </tr>
  <tr>
    <td> 43 </td> <td>308</td>
  </tr>
  <tr>
    <td> 44 </td> <td>324</td>
  </tr>
  <tr>
    <td> 45 </td> <td>344</td>
  </tr>
  <tr>
    <td> 46 </td> <td>360</td>
  </tr>
  <tr>
    <td> 47 </td> <td>381</td>
  </tr>
  <tr>
    <td> 48 </td> <td>403</td>
  </tr>
  <tr>
    <td> 49 </td> <td>429</td>
  </tr>
  <tr>
    <td> 50 </td> <td>452</td>
  </tr>
  <tr>
    <td> 51 </td> <td>480</td>
  </tr>
  <tr>
    <td> 52 </td> <td>500</td>
  </tr>
  <tr>
    <td> 53 </td> <td>530</td>
  </tr>
  <tr>
    <td> 54 </td> <td>558</td>
  </tr>
  <tr>
    <td> 55 </td> <td>594</td>
  </tr>
  <tr>
    <td> 56 </td> <td>616</td>
  </tr>
  <tr>
    <td> 57 </td> <td>634</td>
  </tr>
  <tr>
    <td> 58 </td> <td>664</td>
  </tr>
  <tr>
    <td> 59 </td> <td>694</td>
  </tr>
  <tr>
    <td> 60 </td> <td>730</td>
  </tr>
  <tr>
    <td> 61 </td> <td>760</td>
  </tr>
  <tr>
    <td> 62 </td> <td>790</td>
  </tr>
  <tr>
    <td> 63 </td> <td>826</td>
  </tr>
  <tr>
    <td> 64 </td> <td>864</td>
  </tr>
</table>
</details>


###### minecraft:scattered_ore
`minecraft:ore`と大体同じです。
こちらはやや分散した感じで生成されます。
configの書き方も`ore`と同じです。

##### minecraft:disk
円状にブロックを置換します。
川底や沼地の底に見られるアレです。
<div align="right"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/b4b8f467-5c91-58a8-c012-65d9adf1f95e.png" width=50%></div>

実はこの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`には偏差を指定します。

<!--
![2023-12-16_18.17.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/4356b26b-fe30-f84c-2b34-7c7bacebcdcd.png)
-->

##### 参考画像
###### coral_claw
![2023-12-16_18.17.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/4356b26b-fe30-f84c-2b34-7c7bacebcdcd.png)

###### coral_tree
![2023-12-16_18.17.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/ae5ee2c6-e70d-9a25-bc5a-9dcba61582a6.png)

###### coral_mushroom
![2023-12-16_18.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/a1239ed4-24bb-0afb-27fd-11fb5257a36f.png)

###### dripstone_cluster
![2023-12-16_19.35.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/612c05e6-64da-daa8-e7be-ca7dba8e26dd.png)

###### large_dripstone
![2023-12-16_19.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/1118f87d-46bc-a1bb-0093-bee444d2c7eb.png)

# 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"なくなってるしね。
(画像のは再現です）![2023-12-20_07.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/66103534-d369-2a48-effd-b9d71b5bc9d7.png)

##### 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とは「台形」という意味です。台形や三角形を描くように、指定した高度範囲の最高（低）値から中央値に向かって大きくなっていきます。
…まあ、こんな感じ！この三角形みたいなのがそうです。
![1024px-1-18-ore-distribution.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/cbe10a4a-d17c-aed1-7aba-be0c8af5e415.jpeg)

書き方はこんな感じ
```
{
    "min_inclusive": Height provider,
    "max_inclusive": Height provider,
    "plateau": 整数
}
```
`plateau`は中央部分の長さです。ここを0にすると三角形になります。
中央部分はuniformと同じ扱いになります。

###### minecraft:weighted_list
複数の高度からランダムに選びます。
書き方はこんな感じ。
```
{
    "distribution": [
        {
            "data": 整数/Height provider,
            "weight": 整数
        }
    ]
}
```
それぞれの項目の意味は…
もうわかるよね？

##### minecraft:heightmap
その場所の「最も高い場所」にシフトします。
heightmapについても、[こちら](https://note.com/noir_kokumin/n/n99b336fe95fd#927df0b8-bf11-4b4b-9d1b-9aa9ff333b80)で説明してますのでそちらをどうぞ。

##### 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
任意の項目です。この条件を満たした場合、引き続きスキャンを続行します。

#### 試行回数を変えるタイプ
同一のfeatureが指定した数分試行されます。
`minecraft:random_selector`等のランダム性のあるものの場合、結果が決定されたものが試行されます。

基本的に最初に指定します。

##### minecraft:count
試行回数です。
そのチャンクに指定した数だけ**同一の**featureの生成を試行します。
デフォルトは1で、何も指定しなければ1チャンクに1回だけ試行されます。

例えるなら…
会社に必要な資料をコピーして配布する感じです。

`count`という項目が追加され、Int providerで指定します。

##### minecraft:count_on_every_layer
基本的にcountと同じですが、こちらは各高度毎に判定されます。
書き方もcountと同じ。

先程の例えで例えるなら…
会社の各部署ごとに資料をコピーして配布する感じです。

**注意**
高度に関係しているからか、前述の<strong><code>minecraft:height_range</code>と競合</strong>します。
それも厄介なことに**読み込みは出来て**しまうのですが、チャンクの生成時に…
<font color="red"><strong>こうなります。</strong></font>
<figure>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/27a8d6ae-eda4-4975-beb6-248b8b7cc47c.png"/>
<figcaption>これ…シングルプレイです…</figcaption>
</figure>

<!--![2025-05-18_21.24.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591568/27a8d6ae-eda4-4975-beb6-248b8b7cc47c.png)-->

「資料を印刷してから「やっぱり要らないよ」と言われても困る…」ってことなんですかね…。

##### 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`になります。