Entity removed without raising an event

Place to get help with not working mods / modding interface.
Post Reply
mami
Burner Inserter
Burner Inserter
Posts: 18
Joined: Fri Oct 21, 2022 12:27 am
Contact:

Entity removed without raising an event

Post by mami »

Is it possible for an entity to be removed from a world without raising an event?

I have a reoccurring bug in my mod where essential entities seemingly disappear during or before on_configuration_changed without my mod detecting them and updating.

My mod has code that must be run when specific entities are at all removed from the world, or else the mod will crash later. What do I have to do to guarantee that that code gets run on removal. I would like to see the list of events I need to listen to, to double check I got them all, and I would like to know anything else I need to check for.

InappropriatePenguin
Inserter
Inserter
Posts: 29
Joined: Mon Sep 13, 2021 6:53 pm
Contact:

Re: Entity removed without raising an event

Post by InappropriatePenguin »

mami wrote:
Tue Jan 03, 2023 9:07 pm
Is it possible for an entity to be removed from a world without raising an event?
Yes. Any entities destroyed by script using LuaEntity::destroy won't raise any events by default, unless raise_destroy=true is passed in that function call. Players placing waterfill under an entity is one other common one that destroys entities without raising events (though it is now fortunately solvable). Another example is if a surface were to get deleted that has a bunch of entities. You won't get any of the "standard" removal events for those entities that got deleted along with it.
mami wrote:
Tue Jan 03, 2023 9:07 pm
My mod has code that must be run when specific entities are at all removed from the world, or else the mod will crash later. What do I have to do to guarantee that that code gets run on removal. I would like to see the list of events I need to listen to, to double check I got them all, and I would like to know anything else I need to check for.
The "standard" entity-removal events that you want to listen to are on_entity_died, on_player_mined_entity, on_robot_mined_entity, and script_raised_destroy. In these four events, you'll have access to the entity right before it gets destroyed.

There is one special event, on_entity_destroyed, that works a little differently. It fires within 1–2 ticks after entity removal so you won't get a valid entity as part of event data. Instead you'll get the registration_number and the entity's unit_number if it has one. In order for this event to fire for your entities, you have to have pre-registered them using register_on_entity_destroyed.

While that event might solve most of your issues, it's still not perfect because of the 1–2 ticks it might take for it to fire. Ultimately, there's no real substitute to verifying the validity of any LuaEntity you stored a reference to in global before trying to access it. Once you do come across an invalid entity there, you ought to have a way of skipping it and/or removing it from your data structures.

mami
Burner Inserter
Burner Inserter
Posts: 18
Joined: Fri Oct 21, 2022 12:27 am
Contact:

Re: Entity removed without raising an event

Post by mami »

to clarify, is on_entity_destroyed guaranteed to fire after removal no matter what?

mami
Burner Inserter
Burner Inserter
Posts: 18
Joined: Fri Oct 21, 2022 12:27 am
Contact:

Re: Entity removed without raising an event

Post by mami »

Also if I come across an invalid entity in global, is there a safe way to figure out what its unit_number was? A large part of why I can't use that solution, at least not easily and efficiently, is because I have some data structures that are indexed by the unit_number that need to be updated about the removed entity.

InappropriatePenguin
Inserter
Inserter
Posts: 29
Joined: Mon Sep 13, 2021 6:53 pm
Contact:

Re: Entity removed without raising an event

Post by InappropriatePenguin »

mami wrote:
Wed Jan 04, 2023 3:58 am
to clarify, is on_entity_destroyed guaranteed to fire after removal no matter what?
Yes, it is guaranteed to fire no matter what made your entity stop existing. The caveat is that it could take 1–2 ticks before the event fires and you have to register each entity you want that event to be raised for. Note that you will also be getting events for entities that other mods have registered in the same way.
mami wrote:
Wed Jan 04, 2023 4:02 am
Also if I come across an invalid entity in global, is there a safe way to figure out what its unit_number was? A large part of why I can't use that solution, at least not easily and efficiently, is because I have some data structures that are indexed by the unit_number that need to be updated about the removed entity.
Not from an invalid entity, no. You'll want to set up your data structures in such a way that whenever you're iterating over any group of entities, you know exactly what saved data they map to. If you're iterating over entity references that are stored directly in a table, you'll usually want that table to be indexed by unit_number for that reason.

Post Reply

Return to “Modding help”