Under what conditions do chunks load?

Discussion in 'Spigot Plugin Development' started by Hex_27, Jun 4, 2017.

  1. Right now, my plugin has turrets, which fire at nearby entities. I don't want the turret loop to happen for chunks that are unloaded, but the chunk.isLoaded check isn't really working much. How can I solve this?
  2. What? lol. How is this check "not working"?
  3. The chunk remained loaded while the turret loop was happening, so the check always returned true and the turret loop continued in a chunk nobody was close to.
  4. Chunks are kept in the server's memory based on the render distance you have setup for players via the spigot config.

    If you have a view-distance of 10 chunks then there will be more chunks loaded than if you only have a view-distance of 5 chunks.

    You should limit your code to the range of whatever turret you are making. There is nothing wrong with the API though.
  5. Nothing is wrong with the API, I agree with that.
    But even when players are thousands of blocks away from certain chunks, they remain loaded as long as a turret is in it. Are there other conditions for this?
  6. Yes! Minecraft keeps some chunks loaded, for example chunks with hoppers. That's how people make chunk loaders in vanilla.

    EDIT: Not all hoppers of course, only in some circumstances
  7. But it does have to be something the turrets are causing to have to do that. Is it Chunk.getEntities()?
  8. Maybe just the fact that you have a reference to an entity within that chunk is what keeps it loaded... Not sure though
  9. Turrets use getChunk().getEntities() as a target list of targets. And then the loop checks if the entities are close enough to fire at. Would this cause the chunk to be loaded?

    Well... they're thousands of blocks apart all over the world. Some of them have to be outside the spawn chunks, but all the chunks with turrets in them are always loaded
  10. You know that Location#getChunk() loads the Chunk?
    See https://www.spigotmc.org/threads/when-are-chunks-loaded.58342/ for more information.
  11. I guess I know the cause for it now. But is there a way to check if the chunk can be unloaded? Like a check I can do so I can unload the chunk customly
  12. Use World#isChunkLoaded(x, z) to check if a chunk is loaded.
    Read the thread I linked you in my previous post if you don't know how to use it.
  13. electronicboy

    IRC Staff

    for the specifics, you'd basically have to look over the code, but from my recollection, chucks have a sorta timer in them, operations that require a reference to the internal chunk, will cause that timer to be reset and for the chunk to be marked as active, preventing it from being unloaded.

    In this case, you might be better off checking if you feel that the chunk should be unloaded and unloading it manually,(and, or just) making sure that you at the very least clear up whatever task is actually twiddling with blocks in that region.
  14. Yea, but once the chunk is loaded, doesn't this check fail? It'd mean any chunk that was loaded would stay loaded if a turret is in it. I'd want to unload the chunks if it can be unloaded.
  15. Wouldn't that lead to even more laggy tasks? If I need to loop through all the blocks in the region, wouldn't it lag a lot?
  16. electronicboy

    IRC Staff

    Well, what is likely your problem now is that you're continuously accessing the chunk, e.g. calling getNearbyEntities, which causes the chunk to be marked as active, which stops it from being unloaded by the server normally, or by the fallback chunk GC.

    the only way at this point to get the chunk to unload, is to either stop performing operations that requires the server to access that chunk, and thus mark the chunk as active, or to manually unload the chunk yourself. Shamefully, you now enter a state where you're having to do the servers job of unloading chunks manually, or; you need to find a way to stop twiddling with chunks that have turrets in them that have players too far away, maybe have a periodic task that sweeps all of the turrets and check if they still actually need to be active and loaded and unload them manually.

    there is no reason why you'd even need to consider looking all the blocks in a region
  17. Yea this is the part that I'm looking to do now. Right now, turrets hunt for targets with the chunk.getEntities method (I assume world.getnearbyentities still does the same thing?). But it seems, judging from this thread alone, there's a lot of conditions before a chunk can be unloaded, like
  18. electronicboy

    IRC Staff

    Well, the problem with stuff like hoppers is that they look up chunks in order to check if they can move something, thus triggering a getChunk... internally, which sets the state of the chunk as being active, thus preventing it as being unloaded.
    chunks can also be told to not unload, e.g. in the case of spawn chunk, via methods on the chunks. This one is generally not a concern other than for chunks near the world spawn, which there isn't all too much you can do about stuff like that
  19. So a simple method that checks if any players are within the server's chunk render distance of the chunk would suffice?