Subsurface - build beneath your base!

by Natha

While everyone is looking up to space, other planets and the rest of the universe, there is a whole world buried directly underneath us. Use this opportunity to declutter your factory logistics by routing it under your base and explore the underground!

Content
4 days ago
1.1 - 2.0
6.25K
Environment Mining

b Tunnel entrances disapear?

16 hours ago

I have the strangest bug, tunnel entrances disapear after some time?

I thought this might be intended, but there is no way to dig back up again, so i guess this must be a bug ?

16 hours ago

Can you send me a savegame where this bug happens?
There is already a report for it: https://mods.factorio.com/mod/Subsurface/discussion/67b38c8a63d665d478efc544
IIrc it was because of Maraxsis mod.

15 hours ago

I have Maraxis too yes.

15 hours ago
8 hours ago
(updated 7 hours ago)

Figured it out. Took me two hours

The root cause is an ID collision.

Maraxsis has this code:

maraxsis.on_event({"build", "build-ghost", "super-forced-build"}, function(event)
    maraxsis.execute_later("construct_sand_extractor", 1, event)
end)
function maraxsis.execute_later(function_key, ticks, ...)
        local marked_for_death_render_object = rendering.draw_line {
                color = {0, 0, 0, 0},
                width = 0,
                filled = false,
                from = {0, 0},
                to = {0, 0},
                create_build_effect_smoke = false,
                surface = "nauvis",
                time_to_live = ticks
        }
        storage._delayed_functions = storage._delayed_functions or {}
        storage._delayed_functions[script.register_on_object_destroyed(marked_for_death_render_object)] = {function_key, {...}}
end

This means that on every left click, even if you're holding nothing, a "render object" of a line is created that survives for 1 tick.

However, on_object_destroyed's useful_id isn't unique across different target types. It can happen that a render object's expiry happens to have a useful_id same as a tunnel's entity ID, and this code in Subsurface would trigger:

script.on_event(defines.events.on_object_destroyed, function(event)
    -- entrances can't be mined, but in case they are destroyed by mods we have to handle it
    if storage.pole_links[event.useful_id] and storage.pole_links[event.useful_id].valid then
        local opposite_car = storage.pole_links[event.useful_id].surface.find_entities_filtered{name = {"tunnel-entrance", "tunnel-exit"}, position = storage.pole_links[event.useful_id].position, radius = 1}[1]
        if opposite_car and opposite_car.valid then opposite_car.destroy() end
        storage.pole_links[event.useful_id].destroy()
        storage.pole_links[event.useful_id] = nil
    elseif storage.car_links[event.useful_id] and storage.car_links[event.useful_id].valid then
        local opposite_pole = storage.car_links[event.useful_id].surface.find_entities_filtered{name = {"tunnel-entrance-cable", "tunnel-exit-cable"}, position = storage.car_links[event.useful_id].position, radius = 1}[1]
        if opposite_pole and opposite_pole.valid then opposite_pole.destroy() end
        storage.car_links[event.useful_id].destroy()
        storage.car_links[event.useful_id] = nil

Guarding this event handler with if event.type ~= defines.target_type.entity then return end fixes the problem for me.

If needed, I have a save where a tunnel will get deleted immediately upon the next left click, based on skunk's save.

3 hours ago

Thanks!, Yes, please provide the savegame

2 hours ago

https://limewire.com/d/qGcpL#7BJx8PdmSX

The tunnel at the center should disappear upon left clicking with anything, including attempting to use copy or cut tool, or even empty handed.

New response