<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://forge.gemwire.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SameButDifferent</id>
	<title>Forge Community Wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://forge.gemwire.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SameButDifferent"/>
	<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/wiki/Special:Contributions/SameButDifferent"/>
	<updated>2026-04-30T14:50:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Biome_Modifiers&amp;diff=3278</id>
		<title>Biome Modifiers</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Biome_Modifiers&amp;diff=3278"/>
		<updated>2022-06-15T03:44:57Z</updated>

		<summary type="html">&lt;p&gt;SameButDifferent: Fix typo in biome modifier path&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Biome Modifiers are a data-driven system for modifying biomes. They have the ability to modify biomes in several ways:&lt;br /&gt;
&lt;br /&gt;
* Adding or removing worldgen features and carvers&lt;br /&gt;
* Adding or removing mob spawns and mob spawn costs&lt;br /&gt;
* Modifying the climate of a biome&lt;br /&gt;
* Modifying a biome's client effects, such as water color&lt;br /&gt;
&lt;br /&gt;
= Biome Modifier Types =&lt;br /&gt;
&lt;br /&gt;
To define a new type of biome modifier, begin by implementing a new class that extends &amp;lt;code&amp;gt;BiomeModifier&amp;lt;/code&amp;gt;. BiomeModifiers can usually be implemented as records, to reduce boilerplate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier() implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    // This allows modifications to the given biome via the provided Builder.&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public Codec&amp;lt;? extends BiomeModifier&amp;gt; codec()&lt;br /&gt;
  {&lt;br /&gt;
    // This must return a registered Codec, see Biome Modifier Serializers below.&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware! The modify method is called once per each phase per biome per biome modifier, so it's important to check which phase you're in and only make your changes in one phase.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
{&lt;br /&gt;
  if (phase == Phase.ADD)&lt;br /&gt;
  {&lt;br /&gt;
    // add things to biomes&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Typically we also want to restrict biome modifiers to only apply to certain biomes. We can do that by accepting a HolderSet&amp;lt;Biome&amp;gt; in our constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier(HolderSet&amp;lt;Biome&amp;gt; biomes) implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    if (phase == Phase.ADD &amp;amp;&amp;amp; biomes.contains(biome))&lt;br /&gt;
    {&lt;br /&gt;
      // add things to biomes&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can also accept Holders or HolderSets for other [[Registration#Data_Driven_Entries|datapack registry elements]], such as PlacedFeatures, which allows our BiomeModifier to refer to those elements, which can then be defined in their own JSON files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier(HolderSet&amp;lt;Biome&amp;gt; biomes, Holder&amp;lt;PlacedFeature&amp;gt; feature) implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    // add a feature to all specified biomes&lt;br /&gt;
    if (phase == Phase.ADD &amp;amp;&amp;amp; biomes.contains(biome))&lt;br /&gt;
    {&lt;br /&gt;
      builder.getGenerationSettings().addFeature(Decoration.UNDERGROUND_ORES, feature);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Biome Modifier Serializers =&lt;br /&gt;
&lt;br /&gt;
Each type of biome modifier must have a [[Codecs|Codec]] registered for it; [[Registration#DeferredRegister|Deferred Registers]] are the recommended way to register biome modifier codecs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class YourMod&lt;br /&gt;
{&lt;br /&gt;
  static DeferredRegister&amp;lt;Codec&amp;lt;? extends BiomeModifier&amp;gt;&amp;gt; BIOME_MODIFIER_SERIALIZERS =&lt;br /&gt;
    DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, &amp;quot;yourmodid&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  static RegistryObject&amp;lt;Codec&amp;lt;ExampleBiomeModifier&amp;gt;&amp;gt; EXAMPLE_CODEC = BIOME_MODIFIER_SERIALIZERS.register(&amp;quot;example&amp;quot;, () -&amp;gt;&lt;br /&gt;
    RecordCodecBuilder.create(builder -&amp;gt; builder.group(&lt;br /&gt;
        // declare fields&lt;br /&gt;
        Biome.LIST_CODEC.fieldOf(&amp;quot;biomes&amp;quot;).forGetter(ExampleBiomeModifier::biomes),&lt;br /&gt;
        PlacedFeature.CODEC.fieldOf(&amp;quot;feature&amp;quot;).forGetter(ExampleBiomeModifier::feature)&lt;br /&gt;
      // declare constructor&lt;br /&gt;
      ).apply(builder, ExampleBiomeModifier::new)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can now implement the codec() method in our biome modifier class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier(HolderSet&amp;lt;Biome&amp;gt; biomes, Holder&amp;lt;PlacedFeature&amp;gt; feature) implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    // add a feature to all specified biomes&lt;br /&gt;
    if (phase == Phase.ADD &amp;amp;&amp;amp; biomes.contains(biome))&lt;br /&gt;
    {&lt;br /&gt;
      builder.getGenerationSettings().addFeature(Decoration.UNDERGROUND_ORES, feature);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public Codec&amp;lt;? extends BiomeModifier&amp;gt; codec()&lt;br /&gt;
  {&lt;br /&gt;
    return YourMod.EXAMPLE_CODEC.get();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Biome Modifier JSONs =&lt;br /&gt;
&lt;br /&gt;
Once we've registered a codec for our biome modifier type, we can define jsons for it. Biome modifier jsons must be defined in the directory &amp;lt;code&amp;gt;data/modid/forge/biome_modifier/&amp;lt;/code&amp;gt;; a biome modifier at &amp;lt;code&amp;gt;data/modid/forge/biome_modifier/your_biome_modifier.json&amp;lt;/code&amp;gt; has the namespaced id &amp;lt;code&amp;gt;modid:your_biome_modifier&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Our codec above defines the json format:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;biomes&amp;quot; is a special HolderSet field that accepts a single biome id, [list of biome ids], or #biome_tag.&lt;br /&gt;
* &amp;quot;feature&amp;quot; accepts a single placed feature id. [https://minecraft.fandom.com/wiki/Placed_feature These can be defined in jsons as well].&lt;br /&gt;
* We must also specify &amp;quot;type&amp;quot;: &amp;quot;yourmodid:example&amp;quot; to tell the data loader to use our registered codec to read our json.&lt;br /&gt;
&lt;br /&gt;
A json instance of our biome modifier that adds some feature to badlands biomes might look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;yourmodid:example&amp;quot;,&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#minecraft:is_badlands&amp;quot;,&lt;br /&gt;
  &amp;quot;feature&amp;quot;: &amp;quot;yourmod:some_feature&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Side Note on HolderSets ==&lt;br /&gt;
&lt;br /&gt;
HolderSets are a vanilla feature that, when defined in JSON, can be specified as a single id, list of ids, or tag. Our example above uses a holderset of biomes, so all three of these are valid biome fields:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;forest&amp;quot;,&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: [&amp;quot;forest&amp;quot;, &amp;quot;birch_forest&amp;quot;],&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#is_forest&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Datageneration =&lt;br /&gt;
&lt;br /&gt;
Biome Modifier jsons can be [[Datageneration|datagenerated via GatherDataEvent]]. As biome modifiers are datapack registry objects, this can be done by using JsonCodecProvider#forDatapackRegistry as the data provider. Refer to [[Datageneration/Datapack_Registries]] for additional information on datagenerating datapack registry elements.&lt;br /&gt;
&lt;br /&gt;
= Builtin Biome Modifier Types =&lt;br /&gt;
&lt;br /&gt;
Forge provides the following builtin biome modifier types:&lt;br /&gt;
&lt;br /&gt;
== None ==&lt;br /&gt;
&lt;br /&gt;
A no-op biome modifier type, whose jsons have the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:none&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows pack devs or server operators to disable mods' biome modifiers by overriding their biome modifier jsons with the above.&lt;br /&gt;
&lt;br /&gt;
== Add Features ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type adds placed features to biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:add_features&amp;quot;, // required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:your_biome_tag&amp;quot; // accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;features&amp;quot;: &amp;quot;namespace:your_feature&amp;quot;, // accepts a placed feature id, [list of placed feature ids], or #namespace:feature_tag&lt;br /&gt;
  &amp;quot;step&amp;quot;: &amp;quot;underground_ores&amp;quot; // accepts a Decoration enum name&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decoration steps in order of generation are:&lt;br /&gt;
* raw_generation&lt;br /&gt;
* lakes&lt;br /&gt;
* local_modifications&lt;br /&gt;
* underground_structures&lt;br /&gt;
* surface_structures&lt;br /&gt;
* underground_ores&lt;br /&gt;
* underground_decoration&lt;br /&gt;
* fluid_springs&lt;br /&gt;
* vegetal_decoration&lt;br /&gt;
* top_layer_modification&lt;br /&gt;
&lt;br /&gt;
== Remove Features ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type removes features from biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:remove_features&amp;quot;, // required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:your_biome_tag&amp;quot; // accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;features&amp;quot;: &amp;quot;namespace:your_feature&amp;quot;, // accepts a placed feature id, [list of placed feature ids], or #namespace:feature_tag&lt;br /&gt;
  &amp;quot;steps&amp;quot;: &amp;quot;underground_ores&amp;quot; // optional field specifying a Decoration or list of Decorations to remove features from, defaults to all if not specified&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Add Spawns ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type adds mob spawns to biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:add_spawns&amp;quot;, // Required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:biome_tag&amp;quot;, // Accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;spawners&amp;quot;:&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;namespace:entity_type&amp;quot;, // Type of mob to spawn&lt;br /&gt;
    &amp;quot;weight&amp;quot;: 100, // int, spawn weighting&lt;br /&gt;
    &amp;quot;minCount&amp;quot;: 1, // int, minimum pack size&lt;br /&gt;
    &amp;quot;maxCount&amp;quot;: 4, // int, maximum pack size&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Remove Spawns ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type removes mob spawns from biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:remove_spawns&amp;quot;, // Required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:biome_tag&amp;quot;, // Accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;entity_types&amp;quot;: &amp;quot;#namespace:entitytype_tag&amp;quot; // Accepts an entity type, list, or tag of entitytypes whose spawns are to be removed from the biomes&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Best Practices =&lt;br /&gt;
&lt;br /&gt;
* Avoid using biome modifiers to add vanilla placed features to biomes, as this may cause a feature cycle violation (the game will crash if two biomes have the same two features in their feature lists but in different orders). Placed features can be referenced in biome jsons or added via biome modifiers, but should not be used in both.&lt;/div&gt;</summary>
		<author><name>SameButDifferent</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Biome_Modifiers&amp;diff=3277</id>
		<title>Biome Modifiers</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Biome_Modifiers&amp;diff=3277"/>
		<updated>2022-06-15T03:44:15Z</updated>

		<summary type="html">&lt;p&gt;SameButDifferent: Fix typo in biome modifier path and field&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Biome Modifiers are a data-driven system for modifying biomes. They have the ability to modify biomes in several ways:&lt;br /&gt;
&lt;br /&gt;
* Adding or removing worldgen features and carvers&lt;br /&gt;
* Adding or removing mob spawns and mob spawn costs&lt;br /&gt;
* Modifying the climate of a biome&lt;br /&gt;
* Modifying a biome's client effects, such as water color&lt;br /&gt;
&lt;br /&gt;
= Biome Modifier Types =&lt;br /&gt;
&lt;br /&gt;
To define a new type of biome modifier, begin by implementing a new class that extends &amp;lt;code&amp;gt;BiomeModifier&amp;lt;/code&amp;gt;. BiomeModifiers can usually be implemented as records, to reduce boilerplate.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier() implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    // This allows modifications to the given biome via the provided Builder.&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public Codec&amp;lt;? extends BiomeModifier&amp;gt; codec()&lt;br /&gt;
  {&lt;br /&gt;
    // This must return a registered Codec, see Biome Modifier Serializers below.&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware! The modify method is called once per each phase per biome per biome modifier, so it's important to check which phase you're in and only make your changes in one phase.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
{&lt;br /&gt;
  if (phase == Phase.ADD)&lt;br /&gt;
  {&lt;br /&gt;
    // add things to biomes&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Typically we also want to restrict biome modifiers to only apply to certain biomes. We can do that by accepting a HolderSet&amp;lt;Biome&amp;gt; in our constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier(HolderSet&amp;lt;Biome&amp;gt; biomes) implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    if (phase == Phase.ADD &amp;amp;&amp;amp; biomes.contains(biome))&lt;br /&gt;
    {&lt;br /&gt;
      // add things to biomes&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can also accept Holders or HolderSets for other [[Registration#Data_Driven_Entries|datapack registry elements]], such as PlacedFeatures, which allows our BiomeModifier to refer to those elements, which can then be defined in their own JSON files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier(HolderSet&amp;lt;Biome&amp;gt; biomes, Holder&amp;lt;PlacedFeature&amp;gt; feature) implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    // add a feature to all specified biomes&lt;br /&gt;
    if (phase == Phase.ADD &amp;amp;&amp;amp; biomes.contains(biome))&lt;br /&gt;
    {&lt;br /&gt;
      builder.getGenerationSettings().addFeature(Decoration.UNDERGROUND_ORES, feature);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Biome Modifier Serializers =&lt;br /&gt;
&lt;br /&gt;
Each type of biome modifier must have a [[Codecs|Codec]] registered for it; [[Registration#DeferredRegister|Deferred Registers]] are the recommended way to register biome modifier codecs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class YourMod&lt;br /&gt;
{&lt;br /&gt;
  static DeferredRegister&amp;lt;Codec&amp;lt;? extends BiomeModifier&amp;gt;&amp;gt; BIOME_MODIFIER_SERIALIZERS =&lt;br /&gt;
    DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, &amp;quot;yourmodid&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  static RegistryObject&amp;lt;Codec&amp;lt;ExampleBiomeModifier&amp;gt;&amp;gt; EXAMPLE_CODEC = BIOME_MODIFIER_SERIALIZERS.register(&amp;quot;example&amp;quot;, () -&amp;gt;&lt;br /&gt;
    RecordCodecBuilder.create(builder -&amp;gt; builder.group(&lt;br /&gt;
        // declare fields&lt;br /&gt;
        Biome.LIST_CODEC.fieldOf(&amp;quot;biomes&amp;quot;).forGetter(ExampleBiomeModifier::biomes),&lt;br /&gt;
        PlacedFeature.CODEC.fieldOf(&amp;quot;feature&amp;quot;).forGetter(ExampleBiomeModifier::feature)&lt;br /&gt;
      // declare constructor&lt;br /&gt;
      ).apply(builder, ExampleBiomeModifier::new)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can now implement the codec() method in our biome modifier class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record ExampleBiomeModifier(HolderSet&amp;lt;Biome&amp;gt; biomes, Holder&amp;lt;PlacedFeature&amp;gt; feature) implements BiomeModifier&lt;br /&gt;
{&lt;br /&gt;
  public void modify(Holder&amp;lt;Biome&amp;gt; biome, Phase phase, Builder builder)&lt;br /&gt;
  {&lt;br /&gt;
    // add a feature to all specified biomes&lt;br /&gt;
    if (phase == Phase.ADD &amp;amp;&amp;amp; biomes.contains(biome))&lt;br /&gt;
    {&lt;br /&gt;
      builder.getGenerationSettings().addFeature(Decoration.UNDERGROUND_ORES, feature);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public Codec&amp;lt;? extends BiomeModifier&amp;gt; codec()&lt;br /&gt;
  {&lt;br /&gt;
    return YourMod.EXAMPLE_CODEC.get();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Biome Modifier JSONs =&lt;br /&gt;
&lt;br /&gt;
Once we've registered a codec for our biome modifier type, we can define jsons for it. Biome modifier jsons must be defined in the directory &amp;lt;code&amp;gt;data/modid/forge/biome_modifier/&amp;lt;/code&amp;gt;; a biome modifier at &amp;lt;code&amp;gt;data/modid/forge/biome_modifier/your_biome_modifier.json&amp;lt;/code&amp;gt; has the namespaced id &amp;lt;code&amp;gt;modid:your_biome_modifier&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Our codec above defines the json format:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;biomes&amp;quot; is a special HolderSet field that accepts a single biome id, [list of biome ids], or #biome_tag.&lt;br /&gt;
* &amp;quot;feature&amp;quot; accepts a single placed feature id. [https://minecraft.fandom.com/wiki/Placed_feature These can be defined in jsons as well].&lt;br /&gt;
* We must also specify &amp;quot;type&amp;quot;: &amp;quot;yourmodid:example&amp;quot; to tell the data loader to use our registered codec to read our json.&lt;br /&gt;
&lt;br /&gt;
A json instance of our biome modifier that adds some feature to badlands biomes might look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;yourmodid:example&amp;quot;,&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#minecraft:is_badlands&amp;quot;,&lt;br /&gt;
  &amp;quot;feature&amp;quot;: &amp;quot;yourmod:some_feature&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Side Note on HolderSets ==&lt;br /&gt;
&lt;br /&gt;
HolderSets are a vanilla feature that, when defined in JSON, can be specified as a single id, list of ids, or tag. Our example above uses a holderset of biomes, so all three of these are valid biome fields:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;forest&amp;quot;,&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: [&amp;quot;forest&amp;quot;, &amp;quot;birch_forest&amp;quot;],&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#is_forest&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Datageneration =&lt;br /&gt;
&lt;br /&gt;
Biome Modifier jsons can be [[Datageneration|datagenerated via GatherDataEvent]]. As biome modifiers are datapack registry objects, this can be done by using JsonCodecProvider#forDatapackRegistry as the data provider. Refer to [[Datageneration/Datapack_Registries]] for additional information on datagenerating datapack registry elements.&lt;br /&gt;
&lt;br /&gt;
= Builtin Biome Modifier Types =&lt;br /&gt;
&lt;br /&gt;
Forge provides the following builtin biome modifier types:&lt;br /&gt;
&lt;br /&gt;
== None ==&lt;br /&gt;
&lt;br /&gt;
A no-op biome modifier type, whose jsons have the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:none&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows pack devs or server operators to disable mods' biome modifiers by overriding their biome modifier jsons with the above.&lt;br /&gt;
&lt;br /&gt;
== Add Features ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type adds placed features to biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:add_features&amp;quot;, // required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:your_biome_tag&amp;quot; // accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;features&amp;quot;: &amp;quot;namespace:your_feature&amp;quot;, // accepts a placed feature id, [list of placed feature ids], or #namespace:feature_tag&lt;br /&gt;
  &amp;quot;step&amp;quot;: &amp;quot;underground_ores&amp;quot; // accepts a Decoration enum name&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Decoration steps in order of generation are:&lt;br /&gt;
* raw_generation&lt;br /&gt;
* lakes&lt;br /&gt;
* local_modifications&lt;br /&gt;
* underground_structures&lt;br /&gt;
* surface_structures&lt;br /&gt;
* underground_ores&lt;br /&gt;
* underground_decoration&lt;br /&gt;
* fluid_springs&lt;br /&gt;
* vegetal_decoration&lt;br /&gt;
* top_layer_modification&lt;br /&gt;
&lt;br /&gt;
== Remove Features ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type removes features from biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:remove_features&amp;quot;, // required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:your_biome_tag&amp;quot; // accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;features&amp;quot;: &amp;quot;namespace:your_feature&amp;quot;, // accepts a placed feature id, [list of placed feature ids], or #namespace:feature_tag&lt;br /&gt;
  &amp;quot;steps&amp;quot;: &amp;quot;underground_ores&amp;quot; // optional field specifying a Decoration or list of Decorations to remove features from, defaults to all if not specified&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Add Spawns ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type adds mob spawns to biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:add_spawns&amp;quot;, // Required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:biome_tag&amp;quot;, // Accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;spawners&amp;quot;:&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;namespace:entity_type&amp;quot;, // Type of mob to spawn&lt;br /&gt;
    &amp;quot;weight&amp;quot;: 100, // int, spawn weighting&lt;br /&gt;
    &amp;quot;minCount&amp;quot;: 1, // int, minimum pack size&lt;br /&gt;
    &amp;quot;maxCount&amp;quot;: 4, // int, maximum pack size&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Remove Spawns ==&lt;br /&gt;
&lt;br /&gt;
This biome modifier type removes mob spawns from biomes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;forge:add_spawn&amp;quot;, // Required&lt;br /&gt;
  &amp;quot;biomes&amp;quot;: &amp;quot;#namespace:biome_tag&amp;quot;, // Accepts a biome id, [list of biome ids], or #namespace:biome_tag&lt;br /&gt;
  &amp;quot;entity_types&amp;quot;: &amp;quot;#namespace:entitytype_tag&amp;quot; // Accepts an entity type, list, or tag of entitytypes whose spawns are to be removed from the biomes&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Best Practices =&lt;br /&gt;
&lt;br /&gt;
* Avoid using biome modifiers to add vanilla placed features to biomes, as this may cause a feature cycle violation (the game will crash if two biomes have the same two features in their feature lists but in different orders). Placed features can be referenced in biome jsons or added via biome modifiers, but should not be used in both.&lt;/div&gt;</summary>
		<author><name>SameButDifferent</name></author>
	</entry>
</feed>