Skip to content

On the Topic of Block Replacement

Chris edited this page Nov 15, 2020 · 19 revisions

So, here's the deal. I've been getting a lot of bug reports that are actually just people not fully understanding how block replacement works. If you're considering using BiomeTweaker's block replacement feature, read this, and read it good.

For this whole document, assume that

allBiomes = forAllBiomes()

Replacement Lifecycle

Chunk Creation -> Stone Maps placed (Stone and Water) -> Biome Block Replacement -> Biome Top and Filler Block Placement -> Chunk Population -> Decoration Placement

How Do I Replace Block X with Block Y?

Let's assume you want to replace the Stone that generates naturally with Sandstone. Blocks have something called a Block ID. They are strings that are in the format "owner:blockname". So, Stone is "minecraft:stone" and Sandstone is "minecraft:sandstone". This also applies for mods, but you'll have to look it up yourself. So, replacing Stone with Sandstone can be done with

allBiomes.registerGenBlockRep("minecraft:stone", "minecraft:sandstone")

See the the official documentation for more info on the command.

Now the Top and Filler Blocks Aren't Generating!

That's because Minecraft looks for Stone when placing down top and filler blocks. They aren't placed on top of the stone, the top layer of stone is actually replaced. If, you for instance, replaced all the stone with sandstone, Minecraft won't see any Stone to replace. To remedy this, you need to tell BiomeTweaker to tell Minecraft the block has changed.

allBiomes.addActualFillerBlock("minecraft:sandstone")

See the the official documentation for more info on the command. It is disabled by default. Requires BiomeTweakerCore.

Setting the Replacement Stage and World

With v3.0, you have the option of specifying which replacement stage and world you want. See the setPlacementStage and setWorld commands for more information:

https://github.com/superckl/BiomeTweaker/wiki/Basic-Script-Commands#setplacementstage https://github.com/superckl/BiomeTweaker/wiki/Basic-Script-Commands#setworld

Please note that any stage after "BIOME_BLOCKS" may cause a noticeable amount of lag if you're doing heavy block replacement. Try to keep the heavy duty stuff to "BIOME_BLOCKS" and only finesse in later stages in absolutely necessary. You should not do any replacement during The "PRE_ORES" or "POST_ORES" stages.

Weighting

That's right, you can have weighted block replacement. BiomeTweaker supports having multiple different blocks to replace one block with. How does it work? When BiomeTweaker goes to perform block replacements, it will pull a random entry for that block. All you need to do is specify weights as the first argument:

allBiomes.registerGenBlockRep(3, "minecraft:stone", "minecraft:sandstone", 1)
allBiomes.registerGenBlockRep(6, "minecraft:stone", "minecraft:sandstone")
allBiomes.registerGenBlockRep("minecraft:stone", "minecraft:sandstone", 2)

If you don't specify a weight, it will default to 1. Now that new addActualFillerBlock command makes sense, huh? You could have multiple blocks you want to be considered instead of Stone. The entry that gets picked will be held for the entire chunk. But, this poses a problem. What if you don't want your world to look like a 5-year-old's bad art project? BiomeTweaker has just the thing for you:

allBiomes.set("contiguousReplacement", true)

Now BiomeTweaker will carry over the picked entry for all connected chunks of the same biome. Independent swathes of the biome can have separate blocks, but each swathe will have a contiguous replacement.

Advanced Block Replacements

BiomeTweaker also allows you to specify many other parameters for block replacement through the block replacement objects. You can instantiate one like this:

blockRep = newBlockReplacement()

You can then set various properties such as the block and the min and max y. This object can then be passed to the registerGenBlocRep command instead of the second block. An example of replacing stone with andesite above y=60 is given below.

Example:

blockRep = newBlockReplacement()
andesite = forBlock("minecraft:stone")
andesite.setProperty("variant", "andesite")
blockRep.set("block", andesite)
blockRep.set("minY", 60)
allBiomes = forAllBiomes()
allBiomes.registerGenBlockRep("minecraft:stone", blockRep)

The block replacement objects have various properties you can set, they are given below:

  • block - Sets the block this replacement should place.
  • ignoreMeta - If true, this block replacement will not check metadata. For example, if you replace stone with this option set to true, it will also replace granite and andesite.
  • minX, minY, minZ - Sets the minimum coordinate this replacement should happen at. This is in world coordinates.
  • maxX, maxY, maxZ - Sets the maximum coordinate this replacement should happen at. This is in world coordinates.
  • minChunkX, minChunkZ - Sets the minimum chunk coordinate this replacement should happen at. This is in chunk coordinates (0-15).
  • maxChunkX, maxChunkZ - Sets the maximum chunk coordinate this replacement should happen at. This is in chunk coordinates (0-15).
  • contiguous - If true, this replacement will attempt to be contiguous throughout the chunk. If combined with contiguousReplacement from the biome, the world will have contiguous replacements. This is only necessary if you have multiple weighted replacements.