Structure api in Fabric API is inconsistent for structures in Superflat
TelepathicGrunt opened this issue ยท 7 comments
Edit: see bottom-most comment for what is actually happening. The old stuff I said is wrong in many parts
.
.
.
.
.
I registered all my structures using Fabric API's structure api like so:
https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/fe4b301b5609404272858549e4df9cd4b5812e6c/src/main/java/com/telepathicgrunt/repurposedstructures/RSStructures.java#L142
Now I used this method for my structure .superflatFeature(CRIMSON_SHIPWRECK.configure(FeatureConfig.DEFAULT))
as I would like users to have the option to summon my structures in superflat. I assumed this would mean the structure will not spawn in superflat unless the user enters the structure's identifier in the superflat preset string. I feel as if this would be the most logical implementation.
However, in reality, the structures will not spawn the first time you enter a superflat world but when you re-enter it, every structure added will now spawn all at once in new chunks. As you can see, this gets chaotic very fast and probably is not gonna scale when when having a ton of mods do .superflatFeature for their structures. It's already too much for my mod lol. And it also means superflat worlds are now ruined when people go to play on their flat world more than once.
So yeah, the solution would be to make it only spawn the structure if the user specifies the structure's identifier in preset. This way, the superflat world would use vanilla behavior by default and users can change that if they wish. Or if .superflatFeature was suppose to just be for testing purposes, then it should be renamed to .superflatFeatureDebuggingPurpose()
to make that clear that it should not be used in the final product.
Edit: see bottom-most comment for what is actually happening. The old stuff I said is wrong in many parts
.
.
.
.
So I tried to remove superflatFeature from my code to prevent all my structures spawning and possibly ruining people's worlds. However, I found by doing so, exiting and re-entering even a fresh superflat world will crash the game.
Log with the crash when not using superflatFeature: https://hastebin.com/wiveritipu.sql
basically superflat is screwed not matter what. At this point, users shouldn't play superflat at all with structure mods on until the structure api can fix these bugs
Edit: see bottom-most comment for what is actually happening. The old stuff I said is wrong in many parts
.
.
.
.
This is probably also tied to #1113 as well.
When all the structures are spawning, I noticed if I do /locate, the game hangs forever. I am not entirely sure why. I thought it might be related to this. However the Jungle Fortress and RS's Villages are spawning so that means these biome check did pass and the biome has the structure. But for when doing locate command, it might be getting a different result somehow? Or maybe it is hanging somewhere else
https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/70b9a0f0a706428854a6123a0a7074feb3b18ba5/src/main/java/com/telepathicgrunt/repurposedstructures/world/structures/FortressJungleStructure.java#L29-L39
Edit: see bottom-most comment for what is actually happening. The old stuff I said is wrong in many parts
.
.
.
.
Tested with another mod using fapi api and superflatFeature. Their structures does not appear in superflat at all no matter what.
I'm now thinking it's the dimension blacklisting config I added for my structures:
https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/fe4b301b5609404272858549e4df9cd4b5812e6c/src/main/java/com/telepathicgrunt/repurposedstructures/RSAddFeaturesAndStructures.java#L24
So if it is this, then this does point out two things, superflat will not spawn any modded structure unless fapi can add it into the chunk generator spacing as the spacing config is missing. And two, I will need to detect if it is a superflat world and skip doing my structureconfig per dimension stuff. Why does superflat have to be special lmao
Hmm. Now I am curious as to why my structures only showed up after exiting and re-entering superflat. ServerWorldEvents.LOAD might not be firing upon creation of superflat worlds. Might need to test that too...
Ok so yeah it was quite a bit on my end. There's a lot of things at play that caused this issue but in the end, it seems superflat worldtype is just one giant hack lmao
So if a structure is not in FlatChunkGeneratorConfig.STRUCTURE_TO_FEATURES but you attempt to add the structure's StructureConfig directly to the FlatChunkGenerator's StructuresConfig field, the game crashes when entering a superflat world. Fabric API's structure API tries to set dimension's StructuresConfig indirectly by setting StructuresConfig.DEFAULT_STRUCTURES but it seems this does not propagate the structure's StructureConfig to FlatChunkGenerator's field? Very weird and caused me quite some confusion. But this is why the structure API doesn't crash superflat when omitting .superflatFeature() due to the StructuresConfig.DEFAULT_STRUCTURES not reaching superflat and that's why it does crash when you add the config manually.
Now, if you do call .superflatFeature() and you put your structure's StructureConfig into the FlatChunkGenerator's StructuresConfig field on world load, the superflat world will not crash but it will not spawn your structures. I used ServerWorldEvents.LOAD which does indeed fire for world creation so it isn't due to bad timing. Now, if you exit the world and re-enter it, that specific superflat world will start spawning your structures in ungenerated chunks.
Basically, .superflatFeature() alone cannot spawn your structure in superflat. You have to manually add your StructureConfig to the world. But even then, it is still bugged and you have to restart the world for the structure to start spawning.
Ideally, omitting .superflatFeature() should not spawn the structure in superflat (this works fine) and putting on .superflatFeature() should spawn the structure immediately in superflat or make it possible to spawn when added into the superflat preset string (this is what is broken)
Sorry about all the incorrect info I gave before. It was a mess trying to tease out what was going on.
So the configured feature set in by superflatFeature
needs to be attached somewhere for loading?
it seems like the FabricStructureBuilder's defaultConfig field needs to be added to FlatChunkGenerator's StructuresConfig (which holds a Map<StructureFeature<?>, StructureConfig> structures
field)
Edit: multiple FlatChunkGenerator can be made too so this could affect flat modded dimensions as well (not sure why someone would do that but we should assume they will do so). So getting the defaultConfig to all FlatChunkGenerator could prove tricky. I did some cleaning of my code and this is what I do to add my structure's configs to all non-blacklisted dimensions (minus superflat). https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/9337e85bb5f2adda662718f81c3200daa22cd3e3/src/main/java/com/telepathicgrunt/repurposedstructures/RSAddFeaturesAndStructures.java#L26-L41
After that, the structure will spawn in superflat worlds when you make the world, exit, and re-enter. However, I don't why or how to fix it so that the structure spawns right away in superflat without needing to restart the world