Jump to content

[1.11.2] [Solved] Structure Gen freezing the game


GooberGunter

Recommended Posts

Hey, I'm really new to structure gen and have had nothing to go off of other than the source code of mods and the game itself and I think I'm close to getting it to work. However, when I create a new world, it gets stuck at loading world building terrain.

 

Here is my WorldGen class

Spoiler

package com.ninja3659.explorationexpansion.world.gen;

import java.util.Random;

import com.ninja3659.explorationexpansion.world.gen.structure.WorldGenHouse;

import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.fml.common.IWorldGenerator;

public class NeemWorldGenerator implements IWorldGenerator {

	private WorldGenerator house = new WorldGenHouse();
	
	@Override
	public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
		switch(world.provider.getDimension()) {
		case -1:
			break;
		case 0:
			generateOverworld(house, world, random, chunkX*16, chunkZ*16, 10);//you want x16 so that the structure isn't just generated near the origin
			break;
		case 1:
			break;
		}
	}//called any time a chunk is generated
	
	private void generateOverworld(WorldGenerator gen, World world, Random rand, int x, int z, int chance) {
		int randX = x + rand.nextInt(16);//takes the 0/16/32/48 and adds random number between 0 and 15 to have it spawn in any chunk
		int randZ = z + rand.nextInt(16);
		int y = world.getHeight(randX, randZ);
		
		for (int i = 0; i < chance; ++i) {
			gen.generate(world, rand, new BlockPos(randX, y, randZ));
		}
		
	}
	

}

 

 

And here's my WorldGenerator houseGen class

Spoiler

package com.ninja3659.explorationexpansion.world.gen.structure;

import java.util.Random;

import com.ninja3659.explorationexpansion.util.Utils;

import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenerator;

public class WorldGenHouse extends WorldGenerator{
	public boolean isReplaceable(World world, BlockPos pos) {
		IBlockState state = world.getBlockState(pos);
		return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos) ||
				state.getBlock().isWood(world, pos) || state.getBlock() == Blocks.DIRT || 
				state.getBlock() == Blocks.GRASS || state.getBlock().getMaterial(state) == Material.PLANTS;
	}//determines if a block is replaceable
	
	public boolean generate(World world, Random rand, BlockPos pos) {
		int width = 9;
		int length = 9;
		int height = 6;
		
		boolean flag = true;
		
		if(pos.getY() >= 1 && pos.getY() <= 256) {
			for (int hc = pos.getY(); hc <= pos.getY() + height; ++hc) {
				
				int coordcheck = 1;
				
				if(hc == pos.getY())
					coordcheck = -1;//this is one inside
				
				
				BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
				
				for (int checkx = pos.getX() - coordcheck; checkx <=pos.getX() + coordcheck + width; ++checkx) {
					for(int checkz = pos.getZ() - coordcheck; checkz <=pos.getZ() + coordcheck + length; ++checkx){
						if (hc >= 0 && hc < world.getHeight()) {
							if (!this.isReplaceable(world, blockpos$mutableblockpos.setPos(checkx, hc, checkz))) {
								flag = false;
							}//if the place at the checking coords is not replaceable, then fuck it
						}//last check to see that it is in bounds
						else {
							flag = false;
						}//if the check point is out of bounds, then why are you even here
					}//does the same for y
				}//checks the block before the position and the one at the end of the x
			}//Check every layer of the structure
			
			if (!flag) {
				return false;
			}//if flag is false, then your sol
			else {
				//else you somehow managed to survive that, good job
				
				for(int ch = 0; ch <=height; ++ch) {
					for (int cx = 0; ch <=width; ++cx) {
						for (int cz = 0; cz <=length; ++cz) {
							this.setBlockAndNotifyAdequately(world, pos, Blocks.STONEBRICK.getDefaultState());
							Utils.getLogger().info("Built a house boss! at: " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ());
						}//go through x
					}//go through z
				}//go through the y
				
				
				
				
				return true;
				
				
				
			}
		}//then it passes the in world test
		else {
			return false;
		}//if you didn't make it through the first step, bro u didn't have a chance
		
	}
	
	

}

 

 

I may be way off, but I haven't found an up to date tutorial that explains in as much detail as some of the tutorials I've found about making living entities.

Edited by GooberGunter
Link to comment
Share on other sites

Ok....so you registered a world generator that possibly generates a house 10 times per every chunk that gets loaded. In the exact same place as it was the first time it generated in that chunk. Also i think your house is a 9 * 9 * 6 prism of stone brick. Try Not generating it 10 times every chunk and instead make it only appear in 1/50 chunks by removing the for loop in NeemWorldGenerator#generateOverWorld.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

OH! What was I doing?! 

 

I changed it up a bit, making the chances for it to render lower, but still having the problem

 

private void generateOverworld(WorldGenerator gen, World world, Random rand, int x, int z, int chance) {
		int randX = x + rand.nextInt(16);//takes the 0/16/32/48 and adds random number between 0 and 15 to have it spawn in any chunk
		int randZ = z + rand.nextInt(16);
		int y = world.getHeight(randX, randZ);
		
		Random r = new Random();
		
		if(r.nextInt(chance) == 0);
			gen.generate(world, rand, new BlockPos(randX, y, randZ));
		
	}

 

Wait. Nevermind. The if statement wasn't enclosing generate. 

 

When do you use a chunkprovider?

 

Also if anyone knows of any good generation tutorials, could you link them? Thanks

Edited by GooberGunter
Link to comment
Share on other sites

Ok so I updated the classes to: 

GenHouse

Spoiler

package com.ninja3659.explorationexpansion.world.gen.structure;

import java.util.Random;

import com.ninja3659.explorationexpansion.util.Utils;

import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenerator;

public class WorldGenHouse extends WorldGenerator{
	public boolean isReplaceable(World world, BlockPos pos) {
		IBlockState state = world.getBlockState(pos);
		return state.getBlock().isAir(state, world, pos) || state.getBlock().isLeaves(state, world, pos) ||
				state.getBlock().isWood(world, pos) || state.getBlock() == Blocks.DIRT || 
				state.getBlock() == Blocks.GRASS || state.getBlock().getMaterial(state) == Material.PLANTS;
	}//determines if a block is replaceable
	
	public boolean generate(World world, Random rand, BlockPos pos) {
		int width = 9;
		int length = 9;
		int height = 6;
		
		boolean flag = true;
		
		if(pos.getY() >= 1 && pos.getY() <= 256) {
			for (int hc = pos.getY(); hc <= pos.getY() + height; ++hc) {
				
				int coordcheck = 1;
				
				if(hc == pos.getY())
					coordcheck = -1;//this is one inside
				
				
				BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
				
				for (int checkx = pos.getX() - coordcheck; checkx <=pos.getX() + coordcheck + width; ++checkx) {
					for(int checkz = pos.getZ() - coordcheck; checkz <=pos.getZ() + coordcheck + length; ++checkx){
						if (hc >= 0 && hc < world.getHeight()) {
							if (!this.isReplaceable(world, blockpos$mutableblockpos.setPos(checkx, hc, checkz))) {
								flag = false;
							}//if the place at the checking coords is not replaceable, then rip
						}//last check to see that it is in bounds
						else {
							flag = false;
						}//if the check point is out of bounds, then why are you even here
					}//does the same for y
				}//checks the block before the position and the one at the end of the x
			}//Check every layer of the structure
			
			if (!flag) {
				return false;
			}//if flag is false, then your sol
			else {
				//else you somehow managed to survive that, good job
				
				
				//floor
				for (int cx = pos.getX(); cx <= pos.getX()+width; ++cx) {
					for (int cz = pos.getZ(); cz <= pos.getZ() + length; ++cz) {
						BlockPos blockPos = new BlockPos(cx, pos.getY(), cz);
						setBlockAndNotifyAdequately(world, blockPos, Blocks.STONEBRICK.getDefaultState());
					}
				}
				
				
				
				return true;
				
				
				
			}
		}//then it passes the in world test
		else {
			return false;
		}//if you didn't make it through the first step, bro u didn't have a chance
		
	}
	
	

}

 

 

World Generator

Spoiler

package com.ninja3659.explorationexpansion.world.gen;

import java.util.Random;

import com.ninja3659.explorationexpansion.util.Utils;
import com.ninja3659.explorationexpansion.world.gen.structure.WorldGenHouse;

import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkGenerator;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.fml.common.IWorldGenerator;

public class NeemWorldGenerator implements IWorldGenerator {

	private WorldGenerator house = new WorldGenHouse();
	
	@Override
	public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
		switch(world.provider.getDimension()) {
		case -1:
			break;
		case 0:
			generateOverworld(house, world, random, chunkX*16, chunkZ*16, 2000);//you want x16 so that the structure isn't just generated near the origin
			break;
		case 1:
			break;
		}
	}//called any time a chunk is generated
	
	private void generateOverworld(WorldGenerator gen, World world, Random rand, int x, int z, int chance) {
		int randX = x + rand.nextInt(16);//takes the 0/16/32/48 and adds random number between 0 and 15 to have it spawn in any chunk
		int randZ = z + rand.nextInt(16);
		int y = world.getHeight(randX, randZ);
		
		
		if(rand.nextInt(1000) < 1) {
			gen.generate(world, rand, new BlockPos(randX, y, randZ));
			Utils.getLogger().info("here it is at: " + randX + ", " + y + ", " + randZ);

			
		}
	}
	

}

 

I finally got the game to load, but I had to make the spawn chance .1% and I can't find it. The logger isn't logging in these methods either

Link to comment
Share on other sites

51 minutes ago, GooberGunter said:

When do you use a chunkprovider?

If I am not mistaken you do not need a ChunkProvider for Structure Generation.

26 minutes ago, GooberGunter said:

Ok so I updated the classes to: 

I think the biggest problem you have is that you check if the block is replaceable, why? Instead you should get the first ground block at the x, z position you get, and then tell the game to generate your structure. If there are air blocks or plants underneath then simply replace them with a foundation type of block. Kinda like what Minecraft does with it's village buildings, and then clear above your structure by replacing with air. Not all the way up to build height mind you, maybe a couple blocks if the structure is huge and if not clear until there is nothing connected above it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

Step through your code (and into calls) in the debugger. See if you notice recursion (if your structure spills into another chunk, then that chunk may generate another structure and so-on).

  • Like 1

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

Thanks, I cleared that method up and its spawning in the world, but

 

Animefan8888, how would I go about clearing the blocks above it? is there a specific method? Or do I have to literally make a method that places a bunch of air blocks right before the rest is generated?

Link to comment
Share on other sites

2 minutes ago, GooberGunter said:

Thanks, I cleared that method up and its spawning in the world, but

 

Animefan8888, how would I go about clearing the blocks above it? is there a specific method? Or do I have to literally make a method that places a bunch of air blocks right before the rest is generated?

You will have to make a method to do it, I would not necessarily do it before because then you will have to call World#setBlockState more times than necessary. Instead place your building in the world and then clear the area above it. Also do take into account what jeffryfisher said because what he said can and will happen which causes world gen lag because it can spiral out of control. It is called Runaway Chunk Generation.

  • Like 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

So now that I have a better understanding of this. My goal is to have a structure that is about 30x30, could cause runaway chunk generation since it's more than a chunk. So, would this be the case where I use a chunkprovider? If so, how? are there any tutorials on it?

Link to comment
Share on other sites

4 hours ago, GooberGunter said:

So now that I have a better understanding of this. My goal is to have a structure that is about 30x30, could cause runaway chunk generation since it's more than a chunk. So, would this be the case where I use a chunkprovider? If so, how? are there any tutorials on it?

What you will want to do is make a List of ChunkPos that it has generated in. And if the position is to close to one in the list don't generate.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

7 minutes ago, GooberGunter said:

So, I make a list of the chunkPos that the structure spawns in, and set up a boolean that returns false when it's too close to another structure?

Pretty much. At most your structure of 30x30 could belong in 4 chunks. Which means 3 extra chunks are possible when the world is generating, but the problem with that is when it loads those chunks it is possible that, that chunk will also want to generate it there to. There is almost nothing you can do about it taking up four chunks and those chunks generating.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

22 hours ago, GooberGunter said:

how would I go about clearing the blocks above it?

Why would a separate method be needed? Can't a structure include air blocks around and above its  solid blocks?

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

Well yeah, but what I did is I had a new method that had a for loop to replace all blocks in the length width and height of the structure so I could just call a "setBlockState to air" method once. I call this method before I build anything. I just personally find it easier, but maybe this way has its problems

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.

Guest
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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I was just trying to play my modded world when i randomly got this crash for no reason. I sorted through like every mod and eventually I realized it was LLibrary but I can't seem to find a solution to fix the crashing. I can't lose the world that I have that uses this mod please help me. Here's the report: https://pastebin.com/0D00B79i If anyone has a solution please let me know.  
    • 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑   Daftar Slot Ligawin88 adalah bocoran slot rekomendasi gacor dari Ligawin88 yang bisa anda temukan di SLOT Ligawin88. Situs SLOT Ligawin88 hari ini yang kami bagikan di sini adalah yang terbaik dan bersiaplah untuk mengalami sensasi tak terlupakan dalam permainan slot online. Temukan game SLOT Ligawin88 terbaik dengan 100 pilihan provider ternama yang dipercaya akan memberikan kepuasan dan kemenangan hari ini untuk meraih x500. RTP SLOT Ligawin88 merupakan SLOT Ligawin88 hari ini yang telah menjadi pilihan utama bagi pemain judi online di seluruh Indonesia. Setiap harinya jutaan pemain memasuki dunia maya untuk memperoleh hiburan seru dan kemenangan besar dalam bermain slot dengan adanya bocoran RTP SLOT Ligawin88. Tidak ada yang lebih menyenangkan daripada mengungguli mesin slot dan meraih jackpot x500 yang menggiurkan di situs SLOT Ligawin88 hari ini yang telah disediakan SLOT Ligawin88. Menangkan jackpot besar x500 rajanya maxwin dari segala slot dan raih kemenangan spektakuler di situs Ligawin88 terbaik 2024 adalah tempat yang menyediakan mesin slot dengan peluang kemenangan lebih tinggi daripada situs slot lainnya. Bagi anda yang mencari pengalaman judi slot paling seru dan mendebarkan, situs bo SLOT Ligawin88 terbaik 2024 adalah pilihan yang tepat. Jelajahi dunia slot online melalui situs SLOT Ligawin88 di link SLOT Ligawin88.
    • 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑   Daftar Slot Asusslot adalah bocoran slot rekomendasi gacor dari Asusslot yang bisa anda temukan di SLOT Asusslot. Situs SLOT Asusslot hari ini yang kami bagikan di sini adalah yang terbaik dan bersiaplah untuk mengalami sensasi tak terlupakan dalam permainan slot online. Temukan game SLOT Asusslot terbaik dengan 100 pilihan provider ternama yang dipercaya akan memberikan kepuasan dan kemenangan hari ini untuk meraih x500. RTP SLOT Asusslot merupakan SLOT Asusslot hari ini yang telah menjadi pilihan utama bagi pemain judi online di seluruh Indonesia. Setiap harinya jutaan pemain memasuki dunia maya untuk memperoleh hiburan seru dan kemenangan besar dalam bermain slot dengan adanya bocoran RTP SLOT Asusslot. Tidak ada yang lebih menyenangkan daripada mengungguli mesin slot dan meraih jackpot x500 yang menggiurkan di situs SLOT Asusslot hari ini yang telah disediakan SLOT Asusslot. Menangkan jackpot besar x500 rajanya maxwin dari segala slot dan raih kemenangan spektakuler di situs Asusslot terbaik 2024 adalah tempat yang menyediakan mesin slot dengan peluang kemenangan lebih tinggi daripada situs slot lainnya. Bagi anda yang mencari pengalaman judi slot paling seru dan mendebarkan, situs bo SLOT Asusslot terbaik 2024 adalah pilihan yang tepat. Jelajahi dunia slot online melalui situs SLOT Asusslot di link SLOT Asusslot.
    • 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 Daftar Slot Galeri555 adalah bocoran slot rekomendasi gacor dari Galeri555 yang bisa anda temukan di SLOT Galeri555. Situs SLOT Galeri555 hari ini yang kami bagikan di sini adalah yang terbaik dan bersiaplah untuk mengalami sensasi tak terlupakan dalam permainan slot online. Temukan game SLOT Galeri555 terbaik dengan 100 pilihan provider ternama yang dipercaya akan memberikan kepuasan dan kemenangan hari ini untuk meraih x500. RTP SLOT Galeri555 merupakan SLOT Galeri555 hari ini yang telah menjadi pilihan utama bagi pemain judi online di seluruh Indonesia. Setiap harinya jutaan pemain memasuki dunia maya untuk memperoleh hiburan seru dan kemenangan besar dalam bermain slot dengan adanya bocoran RTP SLOT Galeri555. Tidak ada yang lebih menyenangkan daripada mengungguli mesin slot dan meraih jackpot x500 yang menggiurkan di situs SLOT Galeri555 hari ini yang telah disediakan SLOT Galeri555. Menangkan jackpot besar x500 rajanya maxwin dari segala slot dan raih kemenangan spektakuler di situs Galeri555 terbaik 2024 adalah tempat yang menyediakan mesin slot dengan peluang kemenangan lebih tinggi daripada situs slot lainnya. Bagi anda yang mencari pengalaman judi slot paling seru dan mendebarkan, situs bo SLOT Galeri555 terbaik 2024 adalah pilihan yang tepat. Jelajahi dunia slot online melalui situs SLOT Galeri555 di link SLOT Galeri555.
    • 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 🤑DAFTAR & LOGIN🤑 Daftar Slot Kocok303 adalah bocoran slot rekomendasi gacor dari Kocok303 yang bisa anda temukan di SLOT Kocok303. Situs SLOT Kocok303 hari ini yang kami bagikan di sini adalah yang terbaik dan bersiaplah untuk mengalami sensasi tak terlupakan dalam permainan slot online. Temukan game SLOT Kocok303 terbaik dengan 100 pilihan provider ternama yang dipercaya akan memberikan kepuasan dan kemenangan hari ini untuk meraih x500. RTP SLOT Kocok303 merupakan SLOT Kocok303 hari ini yang telah menjadi pilihan utama bagi pemain judi online di seluruh Indonesia. Setiap harinya jutaan pemain memasuki dunia maya untuk memperoleh hiburan seru dan kemenangan besar dalam bermain slot dengan adanya bocoran RTP SLOT Kocok303. Tidak ada yang lebih menyenangkan daripada mengungguli mesin slot dan meraih jackpot x500 yang menggiurkan di situs SLOT Kocok303 hari ini yang telah disediakan SLOT Kocok303. Menangkan jackpot besar x500 rajanya maxwin dari segala slot dan raih kemenangan spektakuler di situs Kocok303 terbaik 2024 adalah tempat yang menyediakan mesin slot dengan peluang kemenangan lebih tinggi daripada situs slot lainnya. Bagi anda yang mencari pengalaman judi slot paling seru dan mendebarkan, situs bo SLOT Kocok303 terbaik 2024 adalah pilihan yang tepat. Jelajahi dunia slot online melalui situs SLOT Kocok303 di link SLOT Kocok303.
  • Topics

×
×
  • Create New...

Important Information

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