There are two issues that I have noticed with fluids on the ground floor during warps.
- Fluid mixing for buildings that have two fluid inputs. (I think this one is pretty well known)
- Extra fluid is generated during warps. I noticed this in my playthrough so far with heavy oil and electrolyte, and watching JohnMegacycle's playthrough it explains why his fusion power is generating extra Fluoroketone.
The extra fluid being generated looks like it is an issue with cloning and the fluid system changes in 2.0+. Basically as each pipe gets cloned it rebalances with all of the other pipes that have already been cloned which results in more fluid than in the original system.
The fluid mixing looks like it may have been around pre 2.0, but based on what I can find both can be solved in the same way.
The only solution that I could come up with after reading up on the modding api:
- Snapshot the fluid amount of all entities before calling game.surfaces[source].clone_area() in the teleport_ground function
- Set the fluid level to 0 after storing the current value
- Add a hook for on_entity_cloned that updates the value back to the snapshot value
I was hoping to try implementing and testing it myself, but I probably won't have time for at least a couple of weeks and thought I should at least share
I vibe coded something close to what I am thinking of if it helps (Apparently all of the spaces for formatting get hidden after posting.):
-- Call this in on_init, on_configuration_changed, and on_runtime_mod_setting_changed
-- This is just creating a list of entities that are able to hold fluid so we can filter on it.
-- Not sure if the platform is big enough to cause a performance hit without this.
local function update_fluid_type_cache()
storage.warptorio.fluid_entity_types = {}
for name, prototype in pairs(prototypes.entity) do
-- Check for fluidbox prototypes (Factorio 2.0 API)
if prototype.fluidbox_prototypes and #prototype.fluidbox_prototypes > 0 then
table.insert(storage.warptorio.fluid_entity_types, name)
end
end
end
-- Add this inside of teleport_ground before calling game.surfaces[source].clone_area()
local warp_fluid_snapshot = {}
local source_entities = source_surface.find_entities_filtered{
area = warp_area,
name = storage.warptorio.fluid_entity_types
}
for _, e in pairs(source_entities) do
-- Double check fluidbox exists on the instance
if e.fluidbox and #e.fluidbox > 0 then
local boxes = {}
for i = 1, #e.fluidbox do
if e.fluidbox[i] then
boxes[i] = {
name = e.fluidbox[i].name,
amount = e.fluidbox[i].amount,
temperature = e.fluidbox[i].temperature
}
-- Clear to prevent the engine from cloning and/or mixing fluid
e.fluidbox[i] = nil
end
end
warp_fluid_snapshot[e.unit_number] = boxes
end
end
-- Add a listener for on_entity_cloned to update the fluid value
script.on_event(defines.events.on_entity_cloned, function(event)
local snapshot = warp_fluid_snapshot[event.source.unit_number]
if snapshot and event.destination.valid then
for i, fluid_data in pairs(snapshot) do
event.destination.fluidbox[i] = fluid_data
end
warp_fluid_snapshot[event.source.unit_number] = nil
end
end)