Jigsaw System (Tutorial)

Started by MrScautHD on Sun, 04/25/2021 - 06:49

Topic category: User side tutorials

Last seen on 14:50, 21. Jun 2021
Joined Apr 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
Jigsaw System (Tutorial)
Sun, 04/25/2021 - 10:58 (edited)

hgfst

This is My Tutorial to make a Jigsaw System in MCreator! (Only for 1.16.x)

Main Tutorial: https://github.com/TelepathicGrunt/StructureTutorialMod

1. you go in you Build.gradle and add the Code

accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')

in the same line as the Minecraft Mappings

Picture:

th

2.Go in your Worspace Folder and add this file https://www.dropbox.com/s/7ior2a10sxeq181/accesstransformer.cfg?dl=1 in the folder

C:\Users\Elias\MCreatorWorkspaces\testsky_1\src\main\resources\META-INF (this is now my Path but you need do this file then in META-INF)

Picture:

fsgsgf

 

3. Make a new Custom Element (with the name "STConfiguredStructures")

and but this Code in it:
 

package "Package Path";

import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.FlatGenerationSettings;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.ResourceLocation;

public class STConfiguredStructures {
	public static StructureFeature<?, ?> CONFIGURED_RUN_DOWN_HOUSE = STStructures.RUN_DOWN_HOUSE.get()
			.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG);
	public static void registerConfiguredStructures() {
		Registry<StructureFeature<?, ?>> registry = WorldGenRegistries.CONFIGURED_STRUCTURE_FEATURE;
		Registry.register(registry, new ResourceLocation(""MODID"", "configured_run_down_house"), CONFIGURED_RUN_DOWN_HOUSE);
		// FlatGenerationSettings.STRUCTURES.put(STStructures.RUN_DOWN_HOUSE.get(),
		// CONFIGURED_RUN_DOWN_HOUSE);
		 FlatGenerationSettings.STRUCTURES.put(STStructures.RUN_DOWN_HOUSE.get(), CONFIGURED_RUN_DOWN_HOUSE);
	}
}

Example Picture:

agf

4.You make a new Element (with the name "STStructures")

package "PACKAGE PATH";


import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
//import com.telepathicgrunt.structuretutorial.structures.RunDownHouseStructure;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.settings.DimensionStructuresSettings;
import net.minecraft.world.gen.settings.StructureSeparationSettings;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.mrscauthd.boss_tools.world.structure.AlienVillageStructure;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class STStructures {

    /**
     * We are using the Deferred Registry system to register our structure as this is the preferred way on Forge.
     * This will handle registering the base structure for us at the correct time so we don't have to handle it ourselves.
     * <p>
     * HOWEVER, do note that Deferred Registries only work for anything that is a Forge Registry. This means that
     * configured structures and configured features need to be registered directly to WorldGenRegistries as there
     * is no Deferred Registry system for them.
     */
    public static final DeferredRegister<Structure<?>> DEFERRED_REGISTRY_STRUCTURE = DeferredRegister.create(ForgeRegistries.STRUCTURE_FEATURES, ""MODID"");

    /**
     * Registers the structure itself and sets what its path is. In this case, the
     * structure will have the resourcelocation of structure_tutorial:run_down_house.
     * <p>
     * It is always a good idea to register your Structures so that other mods and datapacks can
     * use them too directly from the registries. It great for mod/datapacks compatibility.
     * <p>
     * IMPORTANT: Once you have set the name for your structure below and distributed your mod,
     * changing the structure's registry name or removing the structure may cause log spam.
     * This log spam won't break your worlds as forge already fixed the Mojang bug of removed structures wrecking worlds.
     * https://github.com/MinecraftForge/MinecraftForge/commit/56e538e8a9f1b8e6ff847b9d2385484c48849b8d
     * <p>
     * However, users might not know that and think you are to blame for issues that doesn't exist.
     * So it is best to keep your structure names the same as long as you can instead of changing them frequently.
     */
    public static final RegistryObject<Structure<NoFeatureConfig>> RUN_DOWN_HOUSE = DEFERRED_REGISTRY_STRUCTURE.register(""STRUCTURE NAME"", () -> (new AlienVillageStructure(NoFeatureConfig.field_236558_a_)));

    /**
     * This is where we set the rarity of your structures and determine if land conforms to it.
     * See the comments in below for more details.
     */
    public static void setupStructures() {
        setupMapSpacingAndLand(
                RUN_DOWN_HOUSE.get(), /* The instance of the structure */
                new StructureSeparationSettings(24 /* average distance apart in chunks between spawn attempts */,
                        9 /* minimum distance apart in chunks between spawn attempts */,
                        1234567890 /* this modifies the seed of the structure so no two structures always spawn over each-other. Make this large and unique. */),
                true);


        // Add more structures here and so on
    }

    /**
     * Adds the provided structure to the registry, and adds the separation settings.
     * The rarity of the structure is determined based on the values passed into
     * this method in the structureSeparationSettings argument.
     * This method is called by setupStructures above.
     */
    public static <F extends Structure<?>> void setupMapSpacingAndLand(
            F structure,
            StructureSeparationSettings structureSeparationSettings,
            boolean transformSurroundingLand) {
        /*
         * We need to add our structures into the map in Structure class
         * alongside vanilla structures or else it will cause errors.
         *
         * If the registration is setup properly for the structure,
         * getRegistryName() should never return null.
         */
        Structure.NAME_STRUCTURE_BIMAP.put(structure.getRegistryName().toString(), structure);


        /*
         * Whether surrounding land will be modified automatically to conform to the bottom of the structure.
         * Basically, it adds land at the base of the structure like it does for Villages and Outposts.
         * Doesn't work well on structure that have pieces stacked vertically or change in heights.
         *
         * Note: The air space this method will create will be filled with water if the structure is below sealevel.
         * This means this is best for structure above sealevel so keep that in mind.
         *
         * NOISE_AFFECTING_FEATURES requires AccessTransformer  (See resources/META-INF/accesstransformer.cfg)
         */
        if (transformSurroundingLand) {
            Structure.field_236384_t_ =
                    ImmutableList.<Structure<?>>builder()
                            .addAll(Structure.field_236384_t_)
                            .add(structure)
                            .build();

            /*
             * This is the map that holds the default spacing of all structures.
             * Always add your structure to here so that other mods can utilize it if needed.
             *
             * However, while it does propagate the spacing to some correct dimensions from this map,
             * it seems it doesn't always work for code made dimensions as they read from this list beforehand.
             *
             * Instead, we will use the WorldEvent.Load event in StructureTutorialMain to add the structure
             * spacing from this list into that dimension or to do dimension blacklisting properly.
             * We also use our entry in DimensionStructuresSettings.DEFAULTS in WorldEvent.Load as well.
             *
             * DEFAULTS requires AccessTransformer  (See resources/META-INF/accesstransformer.cfg)
             */
            DimensionStructuresSettings.field_236191_b_ =
                    ImmutableMap.<Structure<?>, StructureSeparationSettings>builder()
                            .putAll(DimensionStructuresSettings.field_236191_b_)
                            .put(structure, structureSeparationSettings)
                            .build();


            /*
             * There are very few mods that relies on seeing your structure in the noise settings registry before the world is made.
             *
             * You may see some mods add their spacings to DimensionSettings.BUILTIN_OVERWORLD instead of the NOISE_GENERATOR_SETTINGS loop below but
             * that field only applies for the default overworld and won't add to other worldtypes or dimensions (like amplified or Nether).
             * So yeah, don't do DimensionSettings.BUILTIN_OVERWORLD. Use the NOISE_GENERATOR_SETTINGS loop below instead if you must.
             */
            WorldGenRegistries.NOISE_SETTINGS.getEntries().forEach(settings -> {
                Map<Structure<?>, StructureSeparationSettings> structureMap = settings.getValue().getStructures().func_236195_a_();

                /*
                 * Pre-caution in case a mod makes the structure map immutable like datapacks do.
                 * I take no chances myself. You never know what another mods does...
                 *
                 * structureConfig requires AccessTransformer  (See resources/META-INF/accesstransformer.cfg)
                 */
                if (structureMap instanceof ImmutableMap) {
                    Map<Structure<?>, StructureSeparationSettings> tempMap = new HashMap<>(structureMap);
                    tempMap.put(structure, structureSeparationSettings);
                //    settings.getValue().getStructures().func_236195_a_() = tempMap;
                } else {
                    structureMap.put(structure, structureSeparationSettings);
                }
            });
        }
    }
}

Example Pictures:

sgfd

sgf

sh

5.Make a new Structure (dont forgot this name you need it later to register it!)

Code:

package "PACkAGE PATH";


import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import net.minecraft.entity.EntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.ISeedReader;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.MobSpawnInfo;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.jigsaw.JigsawManager;
import net.minecraft.world.gen.feature.structure.AbstractVillagePiece;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.feature.structure.StructureStart;
import net.minecraft.world.gen.feature.structure.VillageConfig;
import net.minecraft.world.gen.feature.template.TemplateManager;
import net.minecraft.world.gen.placement.IPlacementConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.world.BiomeLoadingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.mrscauthd.boss_tools.BossToolsModElements;
import org.apache.logging.log4j.Level;

import java.util.List;
import java.util.Locale;
import java.util.Random;

public class "STRUCTURE NAME" extends Structure<NoFeatureConfig> {
	//private static Feature<NoFeatureConfig> feature = null;
	//private static ConfiguredFeature<?, ?> configuredFeature = null;
	public AlienVillageStructure(Codec<NoFeatureConfig> codec) {
		super(codec);
		//MinecraftForge.EVENT_BUS.register(this);
		//System.out.println("its works!");
	}

	/**
	 * This is how the worldgen code knows what to call when it
	 * is time to create the pieces of the structure for generation.
	 */
	@Override
	public  IStartFactory<NoFeatureConfig> getStartFactory() {
		return AlienVillageStructure.Start::new;
	}


	/**
	 * Generation stage for when to generate the structure. there are 10 stages you can pick from!
	 * This surface structure stage places the structure before plants and ores are generated.
	 */
	@Override
	public GenerationStage.Decoration getDecorationStage() {
		return GenerationStage.Decoration.SURFACE_STRUCTURES;
	}


	/**
	 * || ONLY WORKS IN FORGE 34.1.12+ ||
	 *
	 * This method allows us to have mobs that spawn naturally over time in our structure.
	 * No other mobs will spawn in the structure of the same entity classification.
	 * The reason you want to match the classifications is so that your structure's mob
	 * will contribute to that classification's cap. Otherwise, it may cause a runaway
	 * spawning of the mob that will never stop.
	 *
	 * NOTE: getDefaultSpawnList is for monsters only and getDefaultCreatureSpawnList is
	 *       for creatures only. If you want to add entities of another classification,
	 *       use the StructureSpawnListGatherEvent to add water_creatures, water_ambient,
	 *       ambient, or misc mobs. Use that event to add/remove mobs from structures
	 *       that are not your own.
	 */
	private static final List<MobSpawnInfo.Spawners> STRUCTURE_MONSTERS = ImmutableList.of(
			new MobSpawnInfo.Spawners(EntityType.ILLUSIONER, 100, 4, 9),
			new MobSpawnInfo.Spawners(EntityType.VINDICATOR, 100, 4, 9)
	);
	@Override
	public List<MobSpawnInfo.Spawners> getDefaultSpawnList() {
		return STRUCTURE_MONSTERS;
	}

	private static final List<MobSpawnInfo.Spawners> STRUCTURE_CREATURES = ImmutableList.of(
			new MobSpawnInfo.Spawners(EntityType.SHEEP, 30, 10, 15),
			new MobSpawnInfo.Spawners(EntityType.RABBIT, 100, 1, 2)
	);
	@Override
	public List<MobSpawnInfo.Spawners> getDefaultCreatureSpawnList() {
		return STRUCTURE_CREATURES;
	}


	/*
	 * This is where extra checks can be done to determine if the structure can spawn here.
	 * This only needs to be overridden if you're adding additional spawn conditions.
	 *
	 * Notice how the biome is also passed in. Though, you are not going to
	 * do any biome checking here as you should've added this structure to
	 * the biomes you wanted already with the biome load event.
	 *
	 * Basically, this method is used for determining if the land is at a suitable height,
	 * if certain other structures are too close or not, or some other restrictive condition.
	 *
	 * For example, Pillager Outposts added a check to make sure it cannot spawn within 10 chunk of a Village.
	 * (Bedrock Edition seems to not have the same check)
	 *
	 *
	 * Also, please for the love of god, do not do dimension checking here. If you do and
	 * another mod's dimension is trying to spawn your structure, the locate
	 * command will make minecraft hang forever and break the game.
	 *
	 * Instead, use the addDimensionalSpacing method in StructureTutorialMain class.
	 * If you check for the dimension there and do not add your structure's
	 * spacing into the chunk generator, the structure will not spawn in that dimension!
	 */
//    @Override
//    protected boolean func_230363_a_(ChunkGenerator chunkGenerator, BiomeProvider biomeSource, long seed, SharedSeedRandom chunkRandom, int chunkX, int chunkZ, Biome biome, ChunkPos chunkPos, NoFeatureConfig featureConfig) {
//        int landHeight = chunkGenerator.getNoiseHeight(chunkX << 4, chunkZ << 4, Heightmap.Type.WORLD_SURFACE_WG);
//        return landHeight > 100;
//    }


	/**
	 * Handles calling up the structure's pieces class and height that structure will spawn at.
	 */
	public static class Start extends StructureStart<NoFeatureConfig>  {
		public Start(Structure<NoFeatureConfig> structureIn, int chunkX, int chunkZ, MutableBoundingBox mutableBoundingBox, int referenceIn, long seedIn) {
			super(structureIn, chunkX, chunkZ, mutableBoundingBox, referenceIn, seedIn);
		}

		@Override
		public void func_230364_a_(DynamicRegistries dynamicRegistryManager, ChunkGenerator chunkGenerator, TemplateManager templateManagerIn, int chunkX, int chunkZ, Biome biomeIn, NoFeatureConfig config) {

			// Turns the chunk coordinates into actual coordinates we can use. (Gets center of that chunk)
			int x = (chunkX << 4) + 7;
			int z = (chunkZ << 4) + 7;

			/*
			 * We pass this into func_242837_a to tell it where to generate the structure.
			 * If func_242837_a's last parameter is true, blockpos's Y value is ignored and the
			 * structure will spawn at terrain height instead. Set that parameter to false to
			 * force the structure to spawn at blockpos's Y value instead. You got options here!
			 */
			BlockPos blockpos = new BlockPos(x, -21, z);

			// All a structure has to do is call this method to turn it into a jigsaw based structure!

			JigsawManager.func_242837_a(
					dynamicRegistryManager,
					new VillageConfig(() -> dynamicRegistryManager.getRegistry(Registry.JIGSAW_POOL_KEY)
							// The path to the starting Template Pool JSON file to read.
							//
							// Note, this is "structure_tutorial:run_down_house/start_pool" which means
							// the game will automatically look into the following path for the template pool:
							// "resources/data/structure_tutorial/worldgen/template_pool/run_down_house/start_pool.json"
							// This is why your pool files must be in "data/<modid>/worldgen/template_pool/<the path to the pool here>"
							// because the game automatically will check in worldgen/template_pool for the pools.
							.getOrDefault(new ResourceLocation(""MODID"", ""YOUR JIGSAW POOL"")),

							// How many pieces outward from center can a recursive jigsaw structure spawn.
							// Our structure is only 1 block out and isn't recursive so any value of 1 or more doesn't change anything.
							// However, I recommend you keep this a high value so people can use datapacks to add additional pieces to your structure easily.
							// But don't make it too large for recursive structures like villages or you'll crash server due to hundreds of pieces attempting to generate!
							25),
					AbstractVillagePiece::new,
					chunkGenerator,
					templateManagerIn,
					blockpos, // Position of the structure. Y value is ignored if last parameter is set to true.
					this.components, // The list that will be populated with the jigsaw pieces after this method.
					this.rand,
					true, // Allow intersecting jigsaw pieces. If false, villages cannot generate houses. I recommend to keep this to true.
					true); // Place at heightmap (top land). Set this to false for structure to be place at blockpos's Y value instead


			// **THE FOLLOWING TWO LINES ARE OPTIONAL**
			//
			// Right here, you can do interesting stuff with the pieces in this.components such as offset the
			// center piece by 50 blocks up for no reason, remove repeats of a piece or add a new piece so
			// only 1 of that piece exists, etc. But you do not have access to the piece's blocks as this list
			// holds just the piece's size and positions. Blocks will be placed later in JigsawManager.
			//
			// In this case, we do `piece.offset` to raise pieces up by 1 block so that the house is not right on
			// the surface of water or sunken into land a bit.
			//
			// Then we extend the bounding box down by 1 by doing `piece.getBoundingBox().minY` which will cause the
			// land formed around the structure to be lowered and not cover the doorstep. You can raise the bounding
			// box to force the structure to be buried as well. This bounding box stuff with land is only for structures
			// that you added to Structure.field_236384_t_ field handles adding land around the base of structures.
			//
			// By lifting the house up by 1 and lowering the bounding box, the land at bottom of house will now be
			// flush with the surrounding terrain without blocking off the doorstep.
			this.components.forEach(piece -> piece.offset(0, 1, 0));
			this.components.forEach(piece -> piece.getBoundingBox().minY -= 1);


			// Sets the bounds of the structure once you are finished.
			this.recalculateStructureSize();

			// I use to debug and quickly find out if the structure is spawning or not and where it is.
			// This is returning the coordinates of the center starting piece.
			//StructureTutorialMain.LOGGER.log(Level.DEBUG, "Rundown House at " +

			// I use to debug and quickly find out if the structure is spawning or not and where it is.
			// This is returning the coordinates of the center starting piece.
		}
		//@SubscribeEvent
		//public void registerFeature(RegistryEvent.Register<Feature<?>> event) {
		//	configuredFeature = feature.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG)
		//			.withPlacement(Placement.NOPE.configure(IPlacementConfig.NO_PLACEMENT_CONFIG));
		//	event.getRegistry().register(feature.setRegistryName("alienvillage"));
		//	Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, new ResourceLocation("boss_tools:alienvillage"), configuredFeature);
		//}
	}
	//@SubscribeEvent
//	public void addFeatureToBiomes(BiomeLoadingEvent event) {
	//	event.getGeneration().getFeatures(GenerationStage.Decoration.SURFACE_STRUCTURES).add(() -> configuredFeature);
	//}
}

Example Pictures:

jhs

dkj

dkh

kfjfk

6. Make a new Mod Element (with the name "MobInnet(this is your class to register it)")


package "PACKAGE PATH";

import com.mojang.serialization.Codec;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.FlatChunkGenerator;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.settings.DimensionStructuresSettings;
import net.minecraft.world.gen.settings.StructureSeparationSettings;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.world.BiomeLoadingEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.mrscauthd.boss_tools.itemgroup.SpaceBosstoolsSpawnEggsItemGroup;
import net.mrscauthd.boss_tools.entity.AlienEntity;

import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.fml.DeferredWorkQueue;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.IEventBus;

import net.minecraft.util.ResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.entity.ai.attributes.GlobalEntityTypeAttributes;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.CreatureEntity;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@BossToolsModElements.ModElement.Tag
public class MobInnet extends BossToolsModElements.ModElement {
    /**
     * Do not remove this constructor
     */
    public MobInnet(BossToolsModElements instance) {
        super(instance, 901);
    }

    @SubscribeEvent
    public static void onClientSetup(FMLClientSetupEvent event) {
        // RenderingRegistry.registerEntityRenderingHandler(STEntitys.ROCKET.get(),
        // ((IRenderFactory) RocketRenderer::new));
        // RenderingRegistry.registerEntityRenderingHandler(ALIEN.get(),
        // ((IRenderFactory) AlienRenderer::new));
    }

    @Override
    public void initElements() {
       // FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
        MinecraftForge.EVENT_BUS.register(this);
        //bus.addGenericListener(Structure.class, this::onRegisterStructures);
        IEventBus forgeBus = MinecraftForge.EVENT_BUS;
      //  forgeBus.addListener(EventPriority.HIGH, this::biomeModificationa);

        IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
        STStructures.DEFERRED_REGISTRY_STRUCTURE.register(modEventBus);
        modEventBus.addListener(this::setup2);
        forgeBus.addListener(EventPriority.NORMAL, this::addDimensionalSpacing);
        forgeBus.addListener(EventPriority.HIGH, this::biomeModification);
    }
    public void setup2(final FMLCommonSetupEvent event)
    {
        event.enqueueWork(() -> {
            STStructures.setupStructures();
            STConfiguredStructures.registerConfiguredStructures();
        });
    }

    public void biomeModification(final BiomeLoadingEvent event) {
        RegistryKey.getOrCreateKey(Registry.BIOME_KEY, event.getName());
        if (event.getName().equals(new ResourceLocation(""MODID":"BIOMEID""))) {
            event.getGeneration().getStructures().add(() -> STConfiguredStructures.CONFIGURED_RUN_DOWN_HOUSE);
        }
       // event.getGeneration().getStructures().add(() -> STConfiguredStructures.CONFIGURED_RUN_DOWN_HOUSE);
    }
    private static Method GETCODEC_METHOD;
    public void addDimensionalSpacing(final WorldEvent.Load event) {
        if (event.getWorld() instanceof ServerWorld) {
            ServerWorld serverWorld = (ServerWorld) event.getWorld();
            try {
                if (GETCODEC_METHOD == null)
                    GETCODEC_METHOD = ObfuscationReflectionHelper.findMethod(ChunkGenerator.class, "func_230347_a_");
                ResourceLocation cgRL = Registry.CHUNK_GENERATOR_CODEC.getKey((Codec<? extends ChunkGenerator>) GETCODEC_METHOD.invoke(serverWorld.getChunkProvider().generator));
                if (cgRL != null && cgRL.getNamespace().equals("terraforged")) return;
            } catch (Exception e) {
                // StructureTutorialMain.LOGGER.error("Was unable to check if " + serverWorld.dimension().location() + " is using Terraforged's ChunkGenerator.");
            }
            if(serverWorld.getChunkProvider().getChunkGenerator() instanceof FlatChunkGenerator &&
                    serverWorld.getDimensionType().equals(World.OVERWORLD)){
                return;
            }
            Map<Structure<?>, StructureSeparationSettings> tempMap = new HashMap<>(serverWorld.getChunkProvider().generator.func_235957_b_().func_236195_a_());
            tempMap.putIfAbsent(STStructures.RUN_DOWN_HOUSE.get(), DimensionStructuresSettings.field_236191_b_.get(STStructures.RUN_DOWN_HOUSE.get()));
            //  serverWorld.getChunkProvider().generator.func_235957_b_().func_236195_a_() = tempMap;
            serverWorld.getChunkProvider().generator.func_235957_b_().field_236193_d_ = tempMap;
        }
    }


    @Override
    public void init(FMLCommonSetupEvent event) {
        DeferredWorkQueue.runLater(() -> {
        });
    }

    @Override
    public void serverLoad(FMLServerStartingEvent event) {
    }
}

Example Pictures:

ah

i

dfjhg

Here to a Jigsaw Tutorial Video:

https://www.youtube.com/watch?v=5a4DAkWW3JQ

8.Need you help? My Discord Name:MrScautHD#0350

Edited by MrScautHD on Sun, 04/25/2021 - 10:58
Last seen on 18:45, 21. Jun 2021
Joined Sep 2018
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
ok no
Sun, 04/25/2021 - 11:59

ok no

Last seen on 14:50, 21. Jun 2021
Joined Apr 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
to many code?
Sun, 04/25/2021 - 16:07

to many code?

Last seen on 08:31, 19. Jun 2021
Joined May 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • Tracker tickets:
  • MCreator plugins:
  • Comments:
you should make the tutorial…
Thu, 05/13/2021 - 14:38

you should make the tutorial more user friendly since they will have to compare the code with the code in the pictures :P