TerraformersMC / Biolith

A biome placement mod focusing on configurability and consistent distribution of modded biomes
Other
9 stars 2 forks source link

[Feature Request] `any_of` sub-biome matcher type #12

Closed Apollounknowndev closed 7 months ago

Apollounknowndev commented 7 months ago

For more complex sub-biome placements, having an any_of type would be useful for cutting down the amount of matchers needed.

As an example, I'm working on a datapack that adds a Snowy Cherry Grove. It generates at >0.2 PV, >0.3 C, and >0.45 T. However, here is where I have a bit of a strange situation: Between -0.45 T and -0.15 T, the Snowy Cherry Grove should generate only at < -0.35 humidity. Above -0.15 T, the biome should generate at any humidity. Currently, my sub_biomes list looks like this as a result:

{
  "sub_biomes": [
    {
      "dimension": "minecraft:overworld",
      "target": "minecraft:snowy_slopes",
      "biome": "snowy_cherry_grove:snowy_cherry_grove",
      "matcher": {
        "criteria": [
          {
            "type": "value",
            "target": "peaks_valleys",
            "min": 0.2
          },
          {
            "type": "value",
            "target": "continentalness",
            "min": 0.3
          },
          {
            "type": "value",
            "target": "temperature",
            "min": -0.45,
            "max": -0.15
          },
          {
            "type": "value",
            "target": "humidity",
            "max": -0.35
          }
        ]
      }
    },
    {
      "dimension": "minecraft:overworld",
      "target": "minecraft:snowy_slopes",
      "biome": "snowy_cherry_grove:snowy_cherry_grove",
      "matcher": {
        "criteria": [
          {
            "type": "value",
            "target": "peaks_valleys",
            "min": 0.2
          },
          {
            "type": "value",
            "target": "continentalness",
            "min": 0.3
          },
          {
            "type": "value",
            "target": "temperature",
            "min": -0.15
          }
        ]
      }
    }
  ]
}

This is already a bit difficult to look through and properly understand due to the matcher being split into two, and that's just for one biome! An any_of matcher would make this far less verbose and easier to read.

{
  "sub_biomes": [
    {
      "dimension": "minecraft:overworld",
      "target": "minecraft:snowy_slopes",
      "biome": "snowy_cherry_grove:snowy_cherry_grove",
      "matcher": {
        "criteria": [
          {
            "type": "value",
            "target": "peaks_valleys",
            "min": 0.2
          },
          {
            "type": "value",
            "target": "continentalness",
            "min": 0.3
          },
          {
            "type": "value",
            "target": "temperature",
            "min": -0.45
          },
          {
            "type": "any_of",
            "criterion": [
              {
                "type": "value",
                "target": "humidity",
                "max": -0.35
              },
              {
                "type": "value",
                "target": "temperature",
                "min": -0.15
              }
            ]
          }
        ]
      }
    }
  ]
}
gniftygnome commented 7 months ago

Excellent, thanks for the report. This is why it's alpha right now is so I can go changing the API based on feedback. I'll see what I can cook up for this. (Cherry Grove itself has some pretty funky noise placement so I'm not totally surprised...)

gniftygnome commented 7 months ago

OK, I think how this will look is like the example below. Both type and target are always mandatory, because they are enums and I don't want to infer them in the codecs. This is consistent with Mojang's own implementations, anyway.

I've tested the JSON below using minecraft:desert as the sub-biome and I was able to easily find desert adjacent snowy slopes and cherry grove, so I am pretty much certain it is working. I'll release another alpha with this update after a bit more testing. A fairly large change to the sub-biome internals was required to implement this feature.

As a side-effect, criterion type all_of target criteria is also now available, so things like nesting all_of inside any_of are now possible (although I fear the json involved might be intractably complex).

{
  "sub_biomes": [
    {
      "dimension": "minecraft:overworld",
      "target": "minecraft:snowy_slopes",
      "biome": "snowy_cherry_grove:snowy_cherry_grove",
      "matcher": {
        "criteria": [
          {
            "type": "value",
            "target": "peaks_valleys",
            "min": 0.2
          },
          {
            "type": "value",
            "target": "continentalness",
            "min": 0.3
          },
          {
            "type": "value",
            "target": "temperature",
            "min": -0.45
          },
          {
            "type": "any_of",
            "target": "criteria",
            "criteria": [
              {
                "type": "value",
                "target": "humidity",
                "max": -0.35
              },
              {
                "type": "value",
                "target": "temperature",
                "min": -0.15
              }
            ]
          }
        ]
      }
    }
  ]
}