I'm the author of LittleTiles/CreativeCore and recently I found out that Minecraft has a huge lag spike during unloading chunks if the world contains a lot of tileentities.
How did I find it?
Although the performance of LittleTiles was not bad there used to be quite horrible lag spikes, which occurred rather frequently while the player was moving. It became more and more unbearable. So I made several attempts to fix it, but unfortunately without any success. I couldn't find anything in my code.
A few months later I tried it again, but this time I was ignoring my code, since I suspected it to be an issue caused by Minecraft itself.
The issue itself
Eventually I found that the lag spike was not caused by loading new chunks, but instead while unloading the old ones. After some further investigations I saw those two suspicious looking lines in
So I debugged it and ... yes ... wow. There were 20,000 tileentities in
tileEntitiesToBeRemoved had a size of 3,000. Stepping over it using the debugger took quite a long time.
I finally had found the issue. It's not caused by the amount of traffic or the complexity of tileentities, but caused by the amount of tileentities no matter if there are furnaces or more complicated ones.
This video demonstrates this issue: https://www.youtube.com/watch?v=vTCJbp45pWM
I also reported this issue to Mojang: https://bugs.mojang.com/browse/MC-119686
How did i fix it?
I replaced those two lists with
HashMap<ChunkPos, List<TileEntity>>. So once a chunk will unload one key will be removed instead of iterating through the whole list several times. This completely solved the lag spikes (as shown in the video).
I implemented it in CreativeCore v1.8 and eventually decided to create this pr.
About this PR
loadedTileEntityList from an ArrayList to a
ChunkedTileEntityList, which basically saves all tileentities in a
HashMap<ChunkPos, List<TileEntity>>. Furthermore I added another list to the world (
tileEntitiesChunkToBeRemoved), which contains all chunk positions of unloaded chunks. During each tick those will be removed from
It's still possible unloading a tileentity using the old way, but I changed it for the chunk. A chunk will now call
markChunkForRemoval instead of calling
markTileEntityForRemoval (func_147457_a) for each tileentity.
If there is anything to complain about my naming or the formatting style, just let me know.
Possible mod conflicts
Since CreativeCore changed it already I can ensure that there is currently only one mod it is conflicting with https://github.com/RootsTeam/Embers/issues/237.
As long the iterator is used there are no changes required.
This issue must have existed for several years now. It probably caused a lot of headaches and definitely ruined the experience for many players, especially if you have build a lot of machines or other stuff close together. So I really hope this improves our modding situation. It affects the server in the same way as the client, only that it might be worse for the server (more loaded tileentities).
I'm looking forward to smoother gameplay and hope this PR will be merged soon. Once that is done I will create another one for 1.11.2.
All the indexed methods have been implemented. There are bad at performance, but the game will no longer crash of a mod is using them (like Embers).
1.12 Superseded Vanilla Bug