Jump to content

Recommended Posts

Posted (edited)

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
Posted

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.

Posted (edited)

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
Posted

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

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

Posted

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.

Posted

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?

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

Posted

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?

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

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

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

Posted

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

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

    • Hi,  I'm using Forge 47.3.0 for Minecraft 1.20.1 I apologise if this is obvious I am very new to modding for Minecraft. I sucessfully made a mod that launched without errors or crashes (without it doing anything) but in order to add the features I need, I need to add "Custom Portal API [Forge]" as a dependency. However no matter the way I've tried to acheive this, it crashes. I am pretty sure it's not the way I'm putting it in the repositories, the dependencies or the way I'm refrencing it, as I've a hundred diffrent combinations and multiple Maven methods. And on all those diffrent variations I still get this crash: pastebin.com/UhumzZCZ Any tips would be invaluable as I've been loosing my mind over this!
    • Hi, i'm really having problems trying to set the texture to my custom item. I thought i'm doing everything correctly, but all i see is the missing texture block for my item. I am trying this for over a week now and getting really frustrated. The only time i could make the texture work, was when i used an older Forge version (52.0.1) for Minecraft (1.21.4). Was there a fundamental change for textures and models somewhere between versions that i'm missing? I started with Forge 54.1.0 and had this problem, so in my frustration i tried many things: Upgrading to Forge 54.1.1, created multiple new projects, workspaces, redownloaded everything and setting things up multiple times, as it was suggested in an older thread. Therea are no errors in the console logs, but maybe i'm blind, so i pasted the console logs to pastebin anyway: https://pastebin.com/zAM8RiUN The only time i see an error is when i change the models JSON file to an incorrect JSON which makes sense and that suggests to me it is actually reading the JSON file.   I set the github repository to public, i would be so thankful if anyone could take a look and tell me what i did wrong: https://github.com/xLorkin/teleport_pug_forge   As a note: i'm pretty new to modding, this is my first mod ever. But i'm used to programming. I had some up and downs, but through reading the documentation, using google and experimenting, i could solve all other problems. I only started modding for Minecraft because my son is such a big fan and wanted this mod.
    • Please read the FAQ (link in orange bar at top of page), and post logs as described there.
    • Hello fellow Minecrafters! I recently returned to Minecraft and realized I needed a wiki that displays basic information easily and had great user navigation. That’s why I decided to build: MinecraftSearch — a site by a Minecraft fan, for Minecraft fans. Key Features So Far Straight-to-the-Point Info: No extra fluff; just the essentials on items, mobs, recipes, loot and more. Clean & Intuitive Layout: Easy navigation so you spend less time scrolling and more time playing. Optimized Search: Search for anything—items, mobs, blocks—and get results instantly. What I’m Thinking of Adding More data/information: Catch chances for fishing rod, traveling villager trades, biomes info and a lot more. The website is still under development and need a lot more data added. Community Contributions: Potential for user-uploaded tips for items/mobs/blocks in the future. Feature Requests Welcome: Your ideas could shape how the wiki evolves! You can see my roadmap at the About page https://minecraftsearch.com/about I’d love for you to check out MinecraftSearch and see if it helps you find the info you need faster. Feedback is crucial—I want to develop this further based on what the community needs most, so please let me know what you think. Thanks, and happy crafting!
    • Instructions on how to install newer Java can be found in the FAQ
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

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