Jump to content

Recommended Posts

Posted (edited)

I'm currently dealing with a system that stores LivingEntity instances and some related data in a map, based on certain conditions.
In order to prevent memory leakage, I need to remove entries from said map as appropriate.

 

This *could* be accomplished by iterating through every map entry * every entity in every world and seeing if any world contains it, on a timer, but that's a bit inefficient compared to an event-based system.

 

As far as events go, I have not been able to find an event specifically for "any time an entity is unloaded" (latest stable forge release; 2768), but if one exists, please tell me!

 

For now, I tried the next best thing, and used a combination of other events.  This is working for *some* cases but not all.  For example, if I spawn a zombie in an enclosed structure (not in a permanently loaded chunk / "spawn chunk") and move very far away, I receive no messages involving said zombie.  If I place a llama outside the structure, I *do* receive a message for that in the chunk unload.  Also, even if the zombie has a name via nametag, I still receive no message.

Current code:
 

Spoiler

    @SubscribeEvent
    public static void despawn(LivingSpawnEvent.AllowDespawn event)
    {
        EntityLivingBase livingBase = event.getEntityLiving();
        Event.Result result = event.getResult();
        if (livingBase instanceof EntityLiving && result != Event.Result.DENY && result != Event.Result.DEFAULT)
        {
            System.out.println("Despawn " + event.getEntity().getName());
        }
    }

    @SubscribeEvent
    public static void entityDead(LivingDeathEvent event)
    {
        System.out.println("Dead " + event.getEntity().getName());
    }

    @SubscribeEvent
    public static void chunkUnload(ChunkEvent.Unload event)
    {
        Chunk chunk = event.getChunk();
        Set<Entity>[] sets = chunk.getEntityLists();
        for (Set<Entity> set : sets)
        {
            for (Entity entity : set)
            {
                if (entity instanceof EntityLiving) System.out.println("Chunk Unload (saved) " + entity.getName());
            }
        }
    }

    @SubscribeEvent
    public static void worldUnload(WorldEvent.Unload event)
    {
        for (Entity entity : event.getWorld().loadedEntityList)
        {
            if (entity instanceof EntityLiving)
            {
                System.out.println("World Unload " + entity.getName());
            }
        }
    }

 

 

 

Edit: For now, I've supplemented this with the periodic double-iteration I was trying to avoid.  I'm still using the above methods to keep the map size to a minimum and reduce processing due to the periodic iterations.

Edited by Laike_Endaril
Update

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.

Guest
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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Start with removing controllable
    • Please read the FAQ and post logs as described there.
    • Upon starting the server I get; [main/ERROR] [minecraft/Main]: Failed to start the minecraft server net.minecraftforge.fml.LoadingFailedException: Loading errors encountered: [     Framework (framework) has failed to load correctly §7java.lang.NoClassDefFoundError: net/minecraft/client/gui/components/toasts/Toast ] I suspect there is a (possibly a few) client-only mods installed on my server. Any help would be appreciated! (Yes I know there are a lot of mods...) Here is the crash log:   https://paste.ee/p/pRz5mhMl#s=0
    • That's basically what the failure does, my apologies for failing to specify.  It just tries again on the next tick until it detects the entities for that chunk are loaded, and then tries to load the entity.  From there it gets into different failure states depending on what goes wrong, but in short, if the entity fails to load once the entity list becomes available, the request is cleared and must be resubmitted by the end user.  There should be few cases where that actually happens. Yes, that is my understanding of forceloading.  That's why on a successful summon, it removes the forceload.  Otherwise it does just leave the chunks loaded long term. Thank you for your help, any knowledge is useful!  I don't often mess with forceloading and my prior experience is 1.16 so I'm also a bit out of my depth haha.
    • I will have to do more research about 1.18 chunk loading. You were unclear about how your code manages with the entity load failure. If you simply used a loop, I suggest submitting a tick task to the next tick which does the same thing, checking if the entities are loaded and if so teleporting the right one else submitting another tick task etc. Also I think forceloading permanently force loads the chunk, and it only starts to unload when you make a subsequent call to mark the chunk as not forceloaded. I may be completely wrong, I dont know much about 1.18, most of my experience is 1.20. Good luck I hope you figure it out after all this time 😅
  • Topics

×
×
  • Create New...

Important Information

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