CaffeineMC / lithium-fabric

A Fabric mod designed to improve the general performance of Minecraft without breaking things
GNU Lesser General Public License v3.0
1.94k stars 188 forks source link

Optimize /locate command for all structures at an insane rate with a single mixin! #85

Closed TelepathicGrunt closed 4 years ago

TelepathicGrunt commented 4 years ago

Basically in vanilla, if you have a structure that has a very low spacing/separation but is put in a very rare biome, doing /locate could cause the game to stall for minutes or even longer.

The reason for this is because in StructureFeature's locateStructure method, worldView.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.STRUCTURE_STARTS); actually generates the chunk so for something thousands of blocks away, the game is generating every chunk along the way for each structure spawn attempt.

To fix this, go into StructureFeature's locateStructure method and wrap ChunkPos chunkPos down to if (n == 0) with this if statement:

if(worldView.getBiome(mutable.set(trueChunkX << 4, 1, trueChunkZ << 4)).hasStructureFeature(structure)) { Checking if the biome can even spawn the structure first is much, much, MUCH faster than generating the chunk and checking for the structure that way. Why even generate the chunk if the structure is 100% not gonna spawn there because of the invalid biome? smh Mojang.

The good new is this can be done within modded structure by overriding that method like I did here: https://hatebin.com/cfpqkgfskf

But if this can be included in LibStructure, everyone will benefit including vanilla. It would also make treasure maps in chests load much faster as well as they too rely on the /locate command.

For comparison, here's locate command without the fix looking for a Jungle Mineshaft that has a spacing of 1 and separation of 0. It takes a complete full minute while the world hangs and ultimately fails because /locate has a chunk radius of 100 * the structure's spacing config which is about 1600 blocks outward. https://streamable.com/1b0su0

And here's /locate command with the fix finding the Jungle Mineshaft 3500 blocks away in mere seconds (I increased the radius in the locateStructure method I overridden). https://streamable.com/84fx82

(originally was posted on LibStructure but this is a much better fit for Lithium https://github.com/Earthcomputer/LibStructure/issues/1)

2No2Name commented 4 years ago

Thank you for this suggestion. As far as I know your optimization also applies to cartographers creating maps and ender eyes looking for fortresses, so it might be noticeable in survival gameplay as well. Can you read/agree to CONTRIBUTING.md? https://github.com/jellysquid3/lithium-fabric/blob/1.16.x/dev/CONTRIBUTING.md (License is LGPL v3.0)

Also please submit the code as a Pull Request if you can.

TelepathicGrunt commented 4 years ago

Yeah I agree to the CLA and that my code can be relicensed to GNU LGPLv3. I can try and make a PR possibly tomorrow but if you want to implement the code sooner than that, you absolutely can! I really don't need to be credited as it's basically a 1 line fix lol