I wonder if there is any mod uses the on_entity_died event and assumes the entity is killed by anything, leaving a corpse on the ground.
![Confused :?](./images/smilies/icon_e_confused.gif)
Or did I miss something from the API doc?
Edit: also, should I raise the event before or after LuaEntity.destroy()? It returns a boolean, because it is possible that destroy() cannot be executed:
So, it means I have to raise the event after the entity is vanished?Note: Not all entities can be destroyed - things such as rails under trains cannot be destroyed until the train is moved or destroyed.
![Confused :?](./images/smilies/icon_e_confused.gif)
-------------------------------------------------------------------------------
Some background information:
- Problem of LuaEntity.destroy()
Sometimes, we need to know when our entities are destroyed. Example:
When player places entity A, our mod places another hidden entity B. When A is mined, killed or destroyed, B should also be removed via script.
A and B can act naturally as they act in vanilla games, so no extra scripts are required to control them.
Ideally, we listen on_built_entity and on_robot_built_entity to detect when entity A is placed, so we can also place B via script.
Then, we listen on_preplayer_mined_item and on_robot_pre_mined to detect when entity A is mined, so we should remove B.
We listen on_entity_died to detect when A is killed, so we should remove B.
Something is missing... how do we know when A is removed by LuaEntity.destroy()? Sadly, no, we can't.
There is no event for destroy(). This thread aims to ask for the solution for that.
- Can't use die()? It calls on_entity_died!
die() and destroy() behave very differently. die() creates explosion, corpse, particles, loot, etc. which are too troublesome to clear out with find_entities. Some entities, like the turrets, have short delay before they explode after die() was called. It is unpredictable with the current API.
- Our suggestions
1) on_pre_entity_destroyed event - this event would be called after LuaEntity.destroy() is called, but right before the entity becomes invalid. But this suggestion is rejected. Here is a quote of Rseding91 on IRC:
Although we only asked for calling the event after a mod has called LuaEntity.destroy(), as we don't need to know the destruction of other objects like smoke, corpse, etc. we know it is inconsistent to the other events as they also work for the vanilla objects.<Rseding91> Mooncat: you don't understand how many things are destroyed() each game tick by the normal game that would trigger that event if it existed. It's not going to happen. check for valid before accessing something.
2) LuaEntity.can_destroy() - it returns the result of LuaEntity.destroy(), without destroying the entity.
Rseding91 has not responded on this yet, but I think this is going to be rejected. He would just say: "what if a mod place a train on the rail after this method is called?"
![Neutral :|](./images/smilies/icon_neutral.gif)
-------------------------------------------------------------------------------
After the 4-page discussion, we come up to a conclusion:
Sadly, there is no perfect solution. The event system is not ready for events like on_pre_entity_destroyed.
But as Klonan said,
When you use LuaEntity.destroy() to destroy entities that are external from your mod, it is your responsibility to let the other mods know their entities are destroyed.Same with this, if another mods scripting is breaking your mod, it is their issue to fix
A simple, not perfect but working, solution has been suggested by Klonan:
Similarly, if you use LuaSurface.create_entity() to create entities that are not from your mod, you should tell the other mods about that with on_built_entity or on_robot_built_entity.Klonan wrote:Just use on_mined_entity/on_entity_died/on_robot_mined_entity,
When you do you code, like this
That way any mods which remove entities when they die/mined are notified, with a still valid entity reference, after which the entity is destroyed by your script.Code: Select all
function my_function(entity) game.raise_event(on_died) entity.destroy() end
(create_entity() won't trigger any even by default.)
Based on this, aubergine18 has created a nice, small repository: https://github.com/aubergine10/lifecycle-events
Please feel free to use it.
![Wink ;)](./images/smilies/icon_e_wink.gif)
Please note that such events are not needed if your mod can only destroy or create entities that are from your mod, as it will have no impact to other mods, thus not vital for the events to be sent.
You can change the methods such that they accept a boolean for choosing whether to send the events or not.
TL;DR Just check the repository. It is small anyway.
![Laughing :lol:](./images/smilies/icon_lol.gif)
So I guess it is the end of the discussion. Thanks for your precious time for participating and reading this.
![Smile :)](./images/smilies/icon_e_smile.gif)