見出し画像

カスタムディメンジョン ~ Surface rule

はじめに

この記事ではMinecraft 1.18、1.18.1でのカスタムディメンジョンのSurface ruleを触って分かった(と私が勝手に思っている)ことをしたためていきます。
※まだ理解できていない部分も幾つかあり、間違っていることとかあるかもしれません。その場合は遠慮なくコメントやTwitter(@noir_kokumin)にご指摘ください。

Surface rule とは?

Minecraft 1.18にて、Surface builderに置き換わる形で追加された設定で、ワールドやバイオーム等を構成するブロックを決めることができます。
Surface builderでは表面部分しかブロックを指定できず、残りはconfigured_featureでブロック置換をしない限り、default_blockで指定したブロックになっていましたが、今回からは全体のブロックが変更できます。それだけでなく、オーバーワールドの最下層やネザーの最上層にある岩盤層もこちらで設定できます(それに伴ってか、bedrock_roof_positionやbedrock_floor_positionの項目は削除されました)。

Surface ruleの書き方

それでは、書き方についてみていきましょう。
この設定はnoise_settingsファイルの中に書き込み、基本的に

"surface_rule": {
      {"type": type,
       ....
  }

という風に書き込みます。
typeには以下の4つがあります。
block
condition
sequence
bandlands
これらをそれぞれ見ていきましょう(bandlandsは解らないので割愛します)。
(以下、便宜上Ruleと呼びます。)

block

Surface ruleの基本形で、構成ブロックを決めます。
下記にあげるconditionやsequenceなど色々書いていくことがありますが、最終的にはこれにいきつきます。
次のように書きます。

"surface_rule": {
      "result_state": {
        "Name": "block_id",
        {"Properties":blockstates}
      },
     "type": "minecraft:block"
}

{"Properties":blockstates}はblockstatesのないブロックの場合は省略可能です。blockstatesがある場合は、全列挙してください。
例として、ジ・エンドのSurface ruleを見ていきましょう。

"surface_rule": {
    "result_state": {
      "Name": "minecraft:end_stone"
    },
    "type": "minecraft:block"
  }

これだけです。これで、ディメンジョン全部の地形がエンドストーンで構成されます。

ですが、やっぱりこれだと退屈ですよね?
やっぱりバイオームごとに違いを出したいですよね?
そこで、これから「条件」をつけていきます。

condition

先程あげたblockの適用に「条件」を付けます。
次のように書きます。

{
        "type": "minecraft:condition",
        "if_true": {
            "type": condition,
            conditionごとの項目
        },
        "then_run": {
          ...
        }
      }

if文みたいな書き方ですよね。
if_trueで条件をつけ、then_runでRuleを書きます。
then_runで先程あげたblockを指定するわけですが、更に「条件」をつけることもできます。

「条件」には以下の種類があります。
biome
stone_depth
water
y_above
vertical_gradient
noise_threshold
not
hole
steep
temperature
above_preliminary_surface

これらを見ていきましょう。

biome

バイオームを条件にします。
biome_isであげたリストの中にバイオームIDを入れます。

"if_true": {
            "type": "minecraft:biome",
            "biome_is": []
        }

stone_depth

真上または真下が空気の場合にRuleを適用します。

stone_depthの使用例

{
  "offset": int,
  "add_surface_depth": true/false,  // 1.18.1まで
  "secondary_depth_range": int,  // 1.18.2以降
  "surface_type": "ceiling/floor",
  "type": "minecraft:stone_depth"
}

surface_typeで適用先を床か天井かを選びます。これにより、洞窟やネザー等の天井部分のブロックも指定できるわけです。
通常、表面の部分のブロックに適用されますが、add_surface_depthをtrueにしたり、secondary_depth_rangeに数値を設定することで、その下(上)にも適用することができます。
secondary_depth_rangeは1.18.2でadd_surface_secondary_depthが置き換わったものです。add_surface_secondary_depthはbool型(true/falseで指定するやつ)でしたが、こちらは、int型、つまり整数を指定し、指定した数値分Ruleが追加で適用されます。

water

液体(水や溶岩)のある高度の場合、
流体の深さを条件に、Ruleを適用します。ここでいう、「液体」は海や帯水層等、自然生成されたものに限ります。
「水深nブロック以下のとき」という体で条件を指定します。

waterの使用例

"if_true": {
             "type": "minecraft:water",
            "offset": int,
             "surface_depth_multiplier": int,
             "add_stone_depth": true/false
           }

offset
検知したい水深を指定します。基本的にゼロマイナスで指定します。
例えば、ここを4とした場合、水深4ブロック以下の場所でRuleを適用し、0とした場合、液体のない場所を条件とします。

surface_depth_multiplier
検知したい水深の振れ幅になります。
先程のoffsetを水深からこの値を引いたものも検知対象になります。

add_stone_depth
trueにすると、最寄りの水面にシフトし、そこで水深を検知します。

y_above

処理を適用する高さを指定できます。 anchorでabove_bottom、absolute、below_topのどれかを使って「ここより上!」って高さを決めます。 surface_depth_multiplieradd_stone_depthはよく解りません。

"if_true": {
              "type": "minecraft:y_above",
              "anchor": {
                          Choices for a vertical anchor
                        },
              "surface_depth_multiplier": int,
              "add_stone_depth": <true/false>
           }

vertical_gradient

名前にgradientとついてるように、グラデーションのようにブロックが切り替わります。
デフォルトでは岩盤層や深層岩に移り変わるのに使われています。

使用例:オーバーワールドの岩盤層

"if_true": {
          "random_name": "minecraft:bedrock_floor",
          "true_at_and_below": {
            "above_bottom": 0
          },
          "false_at_and_above": {
            "above_bottom": 5
          },
          "type": "minecraft:vertical_gradient"
        }

true_at_and_belowで下端、false_at_and_aboveで上端を決めます。
下端より下は変化後のブロックが使用されます。
random_nameはよく解りませんが、多分割と何だってあり?

noise_threshold

ノイズを条件にRuleを適用します。
min_threshold(最小値)とmax_threshold(最大値)の間に収まっていれば、Ruleが適用されます。
雑にかっこいい模様が作れます。

こんなことができます。

使用例:Frozen Peaksの氷塊の帯

{
  "noise": "minecraft:packed_ice",
   "min_threshold": 0.0,
   "max_threshold": 0.2,
   "type": "minecraft:noise_threshold"
}

not

所謂NOT条件で、invertであげた条件を反転させます

"if_true": {
             "invert": {
                "anchor": {
                    "absolute": 63
                     },
                "surface_depth_multiplier": 0,
                "add_stone_depth": false,
                "type": "minecraft:y_above"
               },
            "type": "minecraft:not"
           }

hole

noiseのうちのsurfaceが0の場合、そこを埋めるようにRuleを適用します。
これを含め、以降のキーはtypeのみになります。

steep

北、東方向に2ブロック以上高低差がある場合、その一番上にRuleを適用します。

temperature

気温が0.15未満の部分にRuleを適用します。ここでいう、「気温」とは降水降雪を決める方です。Multi noiseのパラメータではありません。

above_preliminary_surface

ワールドの一番上の部分にのみRuleを適用します。

sequence

条件分岐を行います。
先程あげた「条件」を場合によって使い分けたいときに使います。

"sequence": [
  {},
  {},
  ...
]

配列型の項目で、配列の中に先程まであげてきたRuleを書いていきます。
感覚的にはswitch文に近く、上からRuleが適用されるかを試し、駄目なら次のRuleを試行する、というのを成功するまで繰り返します。
その為、限定的なものから書いていくといいでしょう。
Ruleの中にはsequenceも含まれているのでsequenceの中にsequenceをネストすることも可能です。

bandlands

メサの地層みたいになります。
これはハードコーディングされており、追加項目はありません。


あとがき

ここまで読んでいただきありがとうございました。
いろいろ理解出来ていない部分がありますが、後々試行を重ねて理解していきたいところです。

Surface ruleって公式含めて説明が殆どないんですよね…
そういう思いもあってこれを書きました。
これからカスタムディメンジョンを遊んでいきたい、という方の助けになれば幸いです。

後々他の設定も書いていくつもりです。

この記事が気に入ったらサポートをしてみませんか?