Air filtering Radius

by Madias

Adds radius effects to the Air Filtering mod by Schorty

Content
8 months ago
2.0
505
Environment

b [Performance] Stuttering every second

6 months ago

Every 60 ticks, there's a noticeable stutter from the significant increase in overhead from this mod.

I know you mention you're no coder, so some tips from one - although I've never made a mod for Factorio, so you may need to apply contextual changes depending on things like scope/built-in methods:

  • Define your functions outside the script.on_nth_tick() call. Right now, you're redefining the functions on every call
  • Store/Cache the locations of the filtering machines, rather than finding all of them again every 60 ticks
  • Define your constants (mk2_chunks/mk3_chunks/etc) just once - outside the scope of the script.on_nth_tick() call
  • Looking at other Factorio mods I've got, it seems like you can use events to trigger function calls. This might be a better way of storing the locations of filtering machines or checking if they're working, etc.
6 months ago

As mentioned, I've never made a Factorio mod before, but I've spent a little while optimising it and this seems to work. There may be some improvements needed. One problem I had was getting the game to properly recognise all the air filtering machines on game-start, so I had to hackily implement the Init check. If I used script.on_init() then it'd only load about 2 or 3 machines until I placed one down to get it to update/refresh.

You're welcome to use this code however you please:

local mk2_chunks = {
    {0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1}    -- Center + Cardinal Directions
}
local mk3_chunks = {
    {0, 0}, {1, 0}, {-1, 0}, {0, 1}, {0, -1},   -- Center + Cardinal
    {2, 0}, {-2, 0}, {0, 2}, {0, -2},           -- 2 Chunks out in cardinal
    {1, 1}, {1, -1}, {-1, 1}, {-1, -1}          -- 1 Chunk diagonally
}

Init = false
Machines = {}


function IsMachineActive(entity)
    if not entity or not entity.valid then return false end

    -- Check if machine has power
    if entity.energy == 0 then
        return false
    end

    -- Check if machine has a filter inside
    local inv = entity.get_inventory(defines.inventory.furnace_source)
    if inv and not inv.is_empty() then
        return true
    end

    return false
end

-- Function to remove pollution within a specified chunk radius
function RemovePollution(base_position, chunk_offsets, removal_amount)
    local surface = game.surfaces[1]
    for _, offset in pairs(chunk_offsets) do
        local chunk_x = math.floor((base_position.x / 32) + offset[1]) * 32
        local chunk_y = math.floor((base_position.y / 32) + offset[2]) * 32
        local pollution = surface.get_pollution({chunk_x, chunk_y})
        surface.pollute({chunk_x, chunk_y}, -math.min(removal_amount, pollution))
    end
end

function FindMachines()
    if not Init then Init = true end
    local surface = game.surfaces[1]
    Machines = surface.find_entities_filtered({name = {"air-filter-machine-mk2", "air-filter-machine-mk3"}})
end

function Execute(e)
    if not Init then FindMachines() end
    for _, machine in pairs(Machines) do
        if IsMachineActive(machine) then
            if machine.name == "air-filter-machine-mk2" then
                RemovePollution(machine.position, mk2_chunks, 50)

            elseif machine.name == "air-filter-machine-mk3" then
                RemovePollution(machine.position, mk3_chunks, 100)
            end
        end
    end
end

-- Update machines when new one is placed
local filter = {
    { filter = "name", name = "air-filter-machine-mk2" },
    { filter = "name", name = "air-filter-machine-mk3", mode = "or"}
}
script.on_event(defines.events.on_built_entity, FindMachines, filter)
script.on_nth_tick(60, Execute)
2 months ago

I can confirm that i am also stuttering, i am also very glad i found out why i was stuttering so thanks Knight_.

New response