lukebemishprojects / BiomeSquisher

New approach to adding biomes to the vanilla Minecraft biome map, using non-linear transforms of biome space to losslessly insert new biomes
BSD 3-Clause "New" or "Revised" License
14 stars 2 forks source link

Biome Squisher

Central Latest Version CodeFactor Snapshot

An innovative new approach to adding biomes to the vanilla Minecraft biome map, Biome Squisher is designed with the goal of being non-destructive, meaning that vanilla biome placement, boundaries, and relative rarities are preserved. Additionally, a secondary goal of Biome Squisher is to work well with multiple biome mods; gone are the days of each worldgen mod present having it's own regions of the world, with only rare borders between them.

So, what's the issue?

In 1.18, Mojang drastically changed how Minecraft selects biomes during worldgen. The new system is extremely powerful, and can be used to create all sorts of breathtaking worldgen, but is difficult for mods to inject their own biomes into in a way that doesn't run into a number of issues. To select a biome at a location, the game first generates a value for 6 different noise functions:

Internally, the game holds a map of a 6D unit cube (though technically the values for these noise functions can go outside of the cube) with each biome having a "region" on it; when determining the biome at a given location, the game looks up the generated noise functions in the "biome space" (that 6D cube) and finds the region the point falls in.

The issue? This biome space is completely filled by vanilla biomes. This makes sense for the vanilla game - what would it mean if you selected a point with no biome at it, after all - but makes adding new biomes in a non-destructive fashion difficult. After all, you can't just shove a biome into the space without clobbering vanilla biomes. Even if you were fine with this, what if two mods want to inject at the same spot? The problem becomes complicated quickly.

Prior art

This is not a new problem - since 1.18, various solutions have arisen. Some well known examples are TerraBlender and Blueprint. Both use a similar, rather clever approach to avoid the issue: for a mod that wishes to add biomes, they create a new "layer" or "slice" - through the use of an additional source of noise - within which the mod has complete control over biome placement - including delegating to the vanilla placement if desired. This allows mods to add biomes without replacing vanilla biomes, and allows multiple biome mods to coexist. However, the approach has a few notable limitations:

A new solution

Biome Squisher takes a different approach to the problem. Instead of adding a new layer, Biome Squisher "squishes" the vanilla biomes (or, in fact, previously added modded biomes) out of the way to open a "hole" in the biome space which a biome can be generated within. To demonstrate visually, the following is a slice along the temperature and humidity axes of the vanilla biome space at fixed values in the other parameters. Each color represents a different biome:

original biome space slice

And after injecting four different biomes into it:

squished biome space slice

Some things to note:

It turns out that the process is not nearly that simple, and there's some pitfalls deal with - for instance, correcting the scale of the in-world noise to not get too many microbiomes, or not "squishing" along the continentalness or depth dimensions where such squishing does not make sense. Biome Squisher accounts for these edge cases and does the math necessary for such "squishing" for you, providing a nice datapack-based API to inject extra biomes into the biome map.

So how do I use this?

Biome Squisher is controlled entirely by datapack. First, a mod defines a series which Biome Squisher will execute on the biome space of the relevant dimension, at data/[namespace]/biomesquisher/series/[path].json. They have the following structure:

Each squisher referenced by a series should be placed at data/[namespace]/biomesquisher/squisher/[path].json. They have the following structure:

Biome Squisher applies registered series in alphabetical order, so that biome injection is platform-independent and deterministic.

The mod provides several commands useful for debugging the biome space in general:

Depending on BiomeSquisher

Available versions of BiomeSquisher are tagged on this repository. BiomeSquisher is available on maven central at dev.lukebemish:biomesquisher; versions for different loaders may be selected by capability.

Adding artifact on NeoForge:

dependencies {
    implementation('dev.lukebemish:biomesquisher:<version>') {
        capabilities {
            requireCapability('dev.lukebemish:biomesquisher-neoforge')
        }
    }
}

Adding artifact on Quilt or Fabric:

dependencies {
    modImplementation('dev.lukebemish:biomesquisher:<version>') {
        capabilities {
            requireCapability('dev.lukebemish:biomesquisher-fabric')
        }
    }
}