Jump to content

[1.16.1] Partly changing JigsawManager's functionality


Recommended Posts

I want to partly change JigsawManager's functionality for my custom structure in mod. However, vanilla JigsawManager is not really that expendible as almost all code is in the same function and some properties are private so the only possible solution currently seems to be to copy whole JigsawManager and manually customize it. This is not really easy and many mappings are missing (both in 1.15.2 and 1.16.1).


This is what I want to achive:

  1. Chose and place first piece from pool "mystructure/entrance."
  2. Start processing all children jigsaw connections.
  3. Normally process all children who aren't in pool "mystructure/special" (but also apply following steps on their children if needed).
  4. If connection's pool is "mystructure/special," chose one piece from that pool. New piece is guaranteed to contain one or more jigsaw connections of that same type/pool. For all of such connections, chose and the exact same piece again with the same orientation. Repeat doing this (chosing the same piece for that pool) until certain condition is meet (y coordinate is almost the same as randomly choosen number between 10 and 50). For all other types/pools, go to step 3 (normally process and place them, but still check for that specific pool). Jigsaw's current depth should not be changed/increased when placing special pieces from pool "mystructure/special," but should be changed/increased normally when placing other pieces.
  5. After that condition is meet, stop placing pieces from "mystructure/special." Place random piece from "mystructure/finish" with same orientation as before, Start placing other pieces normally eith any orientation (step 3).


Thing that pieces from special pool should keep rotation from parent piece is probably easy to do in 1.16 as jigsaws now have joint type aligned which seem to cause them to keep rotation from parent (I'm not sure if this is true so it should still be tested. If it not true, some additional things should be done). However, other things are more advanced and it seems there is no good solution currently.


I found PRs #6378 and #6732 which add events which enable mods to add custom pieces or remove original ones on generation. However, they still don't help me in current state:

  • First PR provides access to ResourceLocation but only fires on init so I can't dynamically check condition.
  • Second PR fires event on generation so I could check for condition (but I can't because of following limitations) but parses ResourceLocation according to "village pool-naming rules" so it may not be the best for custom structures. Parameters like "generalType," "specificType," and "isZombie" should probably be provided and one more village-specific way and raw ResourceLocation should also be accessble.
  • It should be possible to listen for event just on specific structure type to improve performance and make checks easier.
  • They don't provide a way for me to check my condition (no way to check current BlockPos so I can check if y coordinate is correct). This could probably be solved if event also gets BlockPos parameter.
  • They don't provide a way to prevent depth from chaning. This is harder because you can't modify parameter's value because it is passed by value.
  • I don't know if there is any way to chose that random y coordinate for every structure, keep it forever for that structure and access it from event.


Once those limitations are fixed in some way, I could probably implement structure in this way:

  1. Before generation starts, get and save random y coordinate. Also get and save random piece from "mystructure/special" pool. This is part I don't really know how to do.
  2. Listen on event similar to that in #6732. Every time that event is triggered for my specific structure:
  3. Check if target pool is "mystructure/special" and if it is not just skip other steps and return unmodified pool and normally increase depth.
  4. If current y coordinate is bigger/higher than stored random value, remove all existing pieces from pool and add pre-chosen piece into it. Make sure it keeps rotation. Don't increase depth.
  5. If current y coordinate is smaller/lower than stored random value, remove all existing pieces from pool and add random piece from "mystructure/finish" into it.. Make sure it keeps rotation. Don't increase depth. - Then normal generation will start. Because following pieces won't have any connection from "mystructure/special" pool, condition from step 3 won't be evaluated and special generation won't be executed, so there isn't anything special to do.



Do you think it would make sense to improve event handling from those PRs (and merge them)? Would this be a good way to generate such structure? Does joint type in jigsaw blocks prevent rotation like I think it does? How to chose y coordinate and piece for each structure and keep it until generation is done?

If possible, I would like that this is added to Forge 1.16.



Edited by filips
Add few more things
Link to comment
Share on other sites

Yes, that would be one partial solution. However, it has downsides that it requires to make plenty of basically the same pieces (not really a big problem but it makes editing them a bit harder and more confusing) and this will just make that difference in height between top and bottom of structure is random and not random absolute height (if start piece is in y=70 and it randomly choses 10 long piece it will be in y=60 and if it starts in y<40 and choses 38 long piece it will be almost in bedrock, but I always want something random between y=10 and y=50).


If there won't be any other solution, I will use this one but I would prefer something which changes jigsaw generation (maybe with events).

Edited by filips
Link to comment
Share on other sites

you can just create the singleton piece and use a structure block to copy them, a bit tedious but better than changing how vanilla generates structures.


For your problem of absolute height, a dirty solution could be to have multiple structures generate but with different Y levels each and then associate the correct pattern to each.

Instead of having say MyStructure generate between x and y, have MyStructure_50 generate at y = 50, then figure out the max/min length your piece can be and voila. 
its going to be a bit less random for sure (and more tedious), but your structure does sound a bit weird.

Not sure how complex your structure is, but if this is too much you could look into making a normal structure, without any jigsaws. 

Link to comment
Share on other sites

Parts of what you want are already possible.

U can modify JigsawManager with an accesstransformer to add your own JigsawPatterns. Then you should be able to add a Jigsawbased structure like a village, or whatever you want.


I think replacing already choosen JigsawPieces is a much to specific question to be implementet.

Additionally you can extend SingleJigsawPiece to choose at generation (with BlockPos) which you really want to generate.


Because the Jigsawsystem works random makes it difficult to unrandomize it.


Link to comment
Share on other sites

1 hour ago, Cyborgmas said:

its going to be a bit less random for sure (and more tedious), but your structure does sound a bit weird. Not sure how complex your structure is, but if this is too much you could look into making a normal structure, without any jigsaws. 

I agree that this part of structure is quite specific and weird. Basically what I'm trying to do is to make some nice entrance to underground structure. And after entrance is generated, other parts of structure generate normally so it would be harder to create normal structure without jigsaws.


52 minutes ago, cheaterpaul said:

U can modify JigsawManager with an accesstransformer to add your own JigsawPatterns. Then you should be able to add a Jigsawbased structure like a village, or whatever you want.

Ok I will check AccessTransformer and custom JigsawPatterns.


53 minutes ago, cheaterpaul said:

I think replacing already choosen JigsawPieces is a much to specific question to be implementet.

Well, with #6732 you can already do this (I think) and it isn't so specific. It's just that it has to be adopted for modded structures and I would also need access to JigsawBlock's position (which probably also isn't very specific) and that and shouldn't be hard to do. Part with static depth would be harder but I don't really need it.

I would also need one way to get random y coordinate and piece (which I already know how to and doesn't require any modifications to JigsawManager), store them for specific structure and access them from event for that structure (which I don't know how to but hopefully doesn't require public modifications to Forge or JigsawManager).

Link to comment
Share on other sites

So yeah you are def able to replace jigsaw pieces with my PR, ill try and remember to change that to be a bit more modded friendly i guess. The point was to use it on vanilla though. 
A interesting thing that could potentially work with is what @cheaterpaul suggested, create your own custom JigsawPiece. Not sure at all how it works, but sounds interesting. It would count for only 1 depth and potentially when placing you could modify some stuff ? I would say its worth looking into.

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.


  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello. I'm using IntelliJ IDEA and making a mod for Forge 1.20.1 and I'm trying to make a GUI. I found that the Minecraft-related codes are all obfuscated and when setting up the workspace, Gradle did not execute Deobfuscation tasks like createMcpToSrg. Is this normal or a bug? Can anyone help me with this?
    • Hello! I'm trying to get a list of all entries registered in the infusion upgrade registry. Code can be found in github: https://github.com/ChamoisEST/MiningMadness/tree/1.20.1 Registry in common/registries/MMRegistries.java Event that calls the registry is in MiningMadness.java List of registered entries should be called in common/capabilities/infusion/InfusionCapabilityImplementation.java:getActiveInfusions() in the for loop. Is there any way to accomplish that? Thanks in advance!  
    • So, I am trying to create and add tags to my custom damage type, but looks like I made something wrong, since it crashing with error that "cannot register" damage type. Im trying to register it, and in datagen add tags, but it everytime crashing due to not register "grimtales:entropy". Full code there - https://github.com/undertakerJ/Grim-Tales-Forge ModDamageTypes class public class ModDamageTypes { public static final DeferredRegister<DamageType> DAMAGE_TYPES = DeferredRegister.create(Registries.DAMAGE_TYPE, GrimTales.MOD_ID); public static final ResourceKey<DamageType> ENTROPY_KEY = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(GrimTales.MOD_ID, "entropy")); public static final RegistryObject<DamageType> ENTROPY = DAMAGE_TYPES.register( "entropy", () -> new DamageType("entropy_effect", DamageScaling.ALWAYS, 1f, DamageEffects.HURT)); // // public static final DamageSource ENTROPY_SOURCE = new DamageSource(Holder.direct(ENTROPY.get())); public static void register(IEventBus eventBus) { DAMAGE_TYPES.register(eventBus); } } Datagen for damageTags public class ModDamageTagsProvider extends DamageTypeTagsProvider { public ModDamageTagsProvider( PackOutput p_270719_, CompletableFuture<HolderLookup.Provider> p_270256_, @Nullable ExistingFileHelper existingFileHelper) { super(p_270719_, p_270256_, GrimTales.MOD_ID, existingFileHelper); } @Override protected void addTags(HolderLookup.Provider pProvider) { this.tag(DamageTypeTags.BYPASSES_INVULNERABILITY).add(ModDamageTypes.ENTROPY_KEY); } } Datagen class it self   @Mod.EventBusSubscriber(modid = GrimTales.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public class DataGenerators { @SubscribeEvent public static void gatherData(GatherDataEvent event){ DataGenerator generator = event.getGenerator(); PackOutput packOutput = generator.getPackOutput(); ExistingFileHelper helper = event.getExistingFileHelper(); CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider(); generator.addProvider(event.includeServer(), new ModDamageTagsProvider(packOutput, lookupProvider, helper)); } } And register class in main class public GrimTales() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); ModDamageTypes.register(modEventBus); modEventBus.addListener(this::commonSetup); MinecraftForge.EVENT_BUS.register(this); modEventBus.addListener(this::addCreative); }  
    • Looking for a semi-vanilla Minecraft server? Maybe one with keep inventory and land claims? I have one for you! Let me introduce you to Safe Survival! Come on and join us at mc.safesurvival.net. It is bedrock supported too!
    • Hi. I'm trying to play RLCraft with Optifine but my game keeps crashing on startup with Exit Code 1. The modpack was working fine yesterday, not sure what changed to make it not wanna work anymore. I was hoping someone here could help me figure out what's going wrong. If I remove Optifine, nothing changes, I still get the same errors. Thanks in advance. Crash Report (I only included the errors+fatal, I’m not sure if more is needed, please let me know): https://pastebin.ai/66ivknz0f4  
  • Topics

  • Create New...

Important Information

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