Jump to content

[1.12] Replacing Stone in Overworld


Recommended Posts

For my mod, I want to get rid of all the stone blocks in the normal generation and generate my own new stone blocks, different ones for different biomes and such. I have thought about creating a new dimension, un-registering the normal overworld and registering mine in its place. I was wondering if this the best solution, or is there an easier way that I am missing?


Thanks, James

Link to comment
Share on other sites

There is supposed to be a mechanism called a substitution alias that does this for you, but I've never got that to work. For a while after 1.10.2 substitution was supposedly working but I haven't tried it yet and probably not working again.

You can as you mentioned, change generation in your own custom dimension, then you can simply tell your ChunkProvider to generate your own Block instead of stone. 

But what if you want to change generated blocks in other/vanilla dimensions?  Well, here's a way.

However, if you look at ChunkEvent.Load event you'll find that it is called not just upon loading but also immediately after chunk generation. So it is the best place to hook into. Note that this method should be put into a handler class that is registered to the regular EVENT_BUS.  (See my tutorial on events for more information on event handling.)

So here is an example:
public static Block fromBlock = Blocks.GRASS; // change this to suit your need
public static Block toBlock = Blocks.SLIME_BLOCK; // change this to suit your need
@SubscribeEvent(priority=EventPriority.NORMAL, receiveCanceled=true)
public static void onEvent(ChunkEvent.Load event)
  Chunk theChunk = event.getChunk();
  // replace all blocks of a type with another block type

  for (int x = 0; x < 16; ++x) 
     for (int z = 0; z < 16; ++z) 
         for (int y = 0; y < theChunk.getHeightValue(x, z)+1; ++y) 
            if (theChunk.getBlockState(x, y, z).getBlock() == fromBlock)
                theChunk.setBlockState(new BlockPos(x, y, z), toBlock.getDefaultState());
Note: It is possible to further check for the metadata of the block being replaced, and also to set the metadata of the block being replaced.

Note: This will only replace generated blocks. If you really want to replace a block completely in the game you need to also substitute it in the creative menus, possibly intercept any block placement, and if there are recipes that output the block you'll need to replace those.

Tip: Depending on what you want to replace you may want to check different Y-values. Since I was replacing a block normally found on the surface I only looked 20 blocks below the top block. I didn't just look at the top block because in cases of floating islands and overhanging cliffs there were cases where the grass block was not technically the top block.

Warning: If you don't call the markDirty() method, then each time you reload the chunk it will have to replace all the blocks again.  It will still work, but is a waste of performance.
Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

By using this site, you agree to our Terms of Use.