Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[1.16.4] [Solved] Custom Chunk Generator Issues

Featured Replies

Posted

I am currently working on an entirely server side mod that adds a new world type with its own unique chunk generator.

So far the chunk generator works as expected when I load a world for the first time, but if I load the world after closing it, all new chunks are generated with the default overworld chunk generator. In addition, loading these worlds for a second time results in the experimental settings warning screen being displayed.

I am not sure what is causing this behavior, but I suspect it has something to do with my chunk generator's codec (which I still do not fully understand the functionality of) due to this error that I get when loading a world for the first time:

[23:22:20] [Render thread/ERROR] [minecraft/Minecraft]: Error reading worldgen settings after loading data packs: Unknown registry element RegistryLookupCodec[ResourceKey[minecraft:root / minecraft:worldgen/biome]][xmapped]
[23:22:20] [Render thread/ERROR] [minecraft/ServerWorldInfo]: WorldGenSettings: Unknown registry element RegistryLookupCodec[ResourceKey[minecraft:root / minecraft:worldgen/biome]][xmapped]

 

Here is my chunk provider class:

package planetoids.world;

import java.util.ArrayList;

import com.mojang.serialization.Codec;

import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryLookupCodec;
import net.minecraft.world.Blockreader;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
import net.minecraft.world.biome.provider.SingleBiomeProvider;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.WorldGenRegion;
import net.minecraft.world.gen.feature.structure.StructureManager;
import net.minecraft.world.gen.settings.DimensionStructuresSettings;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import planetoids.util.Planetoid;
import planetoids.util.PlanetoidsHandler;
import planetoids.util.PlanetoidsUtil;

public class PlanetoidsChunkGenerator extends ChunkGenerator
{
	public static final Codec<PlanetoidsChunkGenerator> codec = RegistryLookupCodec.getLookUpCodec(Registry.BIOME_KEY).xmap(PlanetoidsChunkGenerator::new, PlanetoidsChunkGenerator::getMainBiome).stable().codec();
	private final Registry<Biome> mainBiome;
	
	public PlanetoidsChunkGenerator(Registry<Biome> biome)
	{
		super(new SingleBiomeProvider(biome.getOrThrow(Biomes.THE_VOID)), new DimensionStructuresSettings(false));
		mainBiome = biome;
	}

	public Registry<Biome> getMainBiome()
	{
		return this.mainBiome;
	}

	protected Codec<? extends ChunkGenerator> func_230347_a_()
	{
		return codec;
	}

	@OnlyIn(Dist.CLIENT)
	public ChunkGenerator func_230349_a_(long p_230349_1_)
	{
		return this;
	}

	public void generateSurface(WorldGenRegion p_225551_1_, IChunk p_225551_2_)
	{
	}

	public int getGroundHeight()
	{
		return 0;
	}
	
	/**
	 * Generate the blocks in a chunk.
	 */
	public void func_230352_b_(IWorld world, StructureManager structureManager, IChunk chunk)
	{
		BlockPos.Mutable blockPos = new BlockPos.Mutable();
		int chunkWorldX = chunk.getPos().getXStart();
		int chunkWorldZ = chunk.getPos().getZStart();
		
		if(chunkWorldX == 0 && chunkWorldZ == 0)
		{
			PlanetoidsHandler.getInstance().generateFirstSolarSystem();
		}
		
		ArrayList<Planetoid> toGenerate = new ArrayList<Planetoid>();
		
		for(Planetoid p : PlanetoidsHandler.getInstance().unloadedPlanetoids)
		{
			if(Math.sqrt(Math.pow(p.getPosition().x - chunkWorldX, 2) + Math.pow(p.getPosition().z - chunkWorldZ, 2)) < p.getRadius() * 4)
				toGenerate.add(p);
		}
		
		for(Planetoid p : PlanetoidsHandler.getInstance().loadedPlanetoids)
		{
			if(Math.sqrt(Math.pow(p.getPosition().x - chunkWorldX, 2) + Math.pow(p.getPosition().z - chunkWorldZ, 2)) < p.getRadius() * 4)
				toGenerate.add(p);
		}
		
		for(Planetoid p : toGenerate)
		{
			for(int i = 0; i < 256; i++)
			{
				if(Math.abs(i - p.getPosition().y) > p.getRadius())
					continue;
				
				for(int j = 0; j < 16; j++)
				{
					for(int k = 0; k < 16; k++)
					{
						Vector3d v = new Vector3d(chunkWorldX + j, i, chunkWorldZ + k);
						
						if(PlanetoidsUtil.getDistance(p.getPosition(), v) < p.getRadius())
							chunk.setBlockState(blockPos.setPos(j, i, k), p.getBlock(v), false);
					}
				}
			}
		}
	}

	public int getHeight(int x, int z, Heightmap.Type heightmapType)
	{
		return 0;
	}

	public IBlockReader func_230348_a_(int p_230348_1_, int p_230348_2_)
	{
		return new Blockreader(new BlockState[0]);
	}
}

 

Edit: Once again I underestimated my ability to solve this kind of problem. It turns out I just needed to rewrite the codec definition and then register it in my main mod file.

Registry.register(Registry.CHUNK_GENERATOR_CODEC, new ResourceLocation(MOD_ID, "chunk_generator"), PlanetoidsChunkGenerator.CODEC);

 

Edited by nanorover59

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

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.