[2.0.76] calling create_entity with fast_replace = true

Place to get help with not working mods / modding interface.
User avatar
hgschmie
Fast Inserter
Fast Inserter
Posts: 186
Joined: Tue Feb 06, 2024 5:18 am
Contact:

[2.0.76] calling create_entity with fast_replace = true

Post by hgschmie »

I have a mod (https://mods.factorio.com/mod/miniloader-redux) where each entity relies on creation/deletion events to maintain internal state. This works fine in the regular game.

I register on_built_entity, on_robot_built_entity, on_space_platform_built_entity, script_raised_built, script_raised_revive as creation events. Each does the same: create an instance of my mod entity around the entity in the event.
I register on_player_mined_entity, on_robot_mined_entity, on_space_platform_mined_entity, script_raised_destroy as deletion events. Same here: If that entity gets destroyed, take the mod entity and its internal pieces down.

In addition, I also register the entity with script.register_on_object_destroyed() and catch the on_object_destroyed event.

In the normal game, when a user uses the upgrade planner, I receive:

- on_robot_mined_entity event for the old entity
- on_robot_built_entity event for the new entity
- on_object_destroyed for the old entity

If a player uses fast replacement (pasting a new entity over the old one), I receive:

- on_player_mined_entity for the old entity
- on_built_entity for the new entity
- on_object_destroyed for the old entity

Now, there is a mod (Blueprint Sandboxes, https://mods.factorio.com/mod/blueprint-sandboxes), which seems to be pretty popular. It creates a magic surface where entities can be built (for interesting values of "built"; It seems that it actually places ghosts which then get revived). If an entity on this surface is either fast-replaced or the upgrade planner is used, it does this:

Code: Select all

-- here entity is valid and should be upgraded
        local targetEntity, targetQuality = entity.get_upgrade_target()

        local options = {
            name = targetEntity.name,
            position = entity.position,
            direction = entity.direction,
            quality = targetQuality,
            force = entity.force,
            fast_replace = true,
            spill = false,
            raise_built = true,
        }

        local result = entity.surface.create_entity(options)
In that case, I receive

- script_raised_built for the new entity
- on_object_destroyed for the old entity

Most importantly I do not receive any destroy event. As fast replacing (same as upgrading) in all other scenarios sends a mined_entity event before sending a built_entity event, I would have expected that in this scenario (raise_built = true and fast_replace = true), the engine would e.g. send out script_raised_destroy. Right now, the creation of the "upgraded" or "fast replaced" entity fails for me because the internal entities can not be created on top of each other.

So I guess, this is 50% asking for clarification, 50% bug report. I believe the engine *should* raise script_raised_destroy IFF create_entity is called with raise_built and fast_replace both being true *and* it is actually fast-replacing an entity (same position and surface and fast-replaceable). Otherwise, custom entities (such as mine) get confused because the "regular" 'destroy old, create new' event sequence does not happen.
User avatar
hgschmie
Fast Inserter
Fast Inserter
Posts: 186
Joined: Tue Feb 06, 2024 5:18 am
Contact:

Re: [2.0.76] calling create_entity with fast_replace = true

Post by hgschmie »

After a bit more experimentation, it seems that the Blueprint Sandboxes mod is doing upgrades wrong. When calling entity.apply_upgrade() instead of create_entity with fast_replace, the engine sends out all events correctly (script_raised_destroy, then script_raised_built).
Post Reply

Return to “Modding help”