A Factorio library mod that provides utilities to spread processing tasks over multiple ticks, helping to maintain game performance when working with large datasets.
Load Spreader allows mod developers to process large collections of objects incrementally across multiple game ticks instead of processing everything in a single tick. This prevents UPS drops and maintains smooth gameplay even when dealing with thousands of entities or complex calculations.
Add Load Spreader as a dependency in your mod's info.json:
{
"dependencies": ["base >= 2.0", "load-spreader >= 1.0.0"]
}Require the library in your mod:
local load_spreader = require("__load-spreader__/load_spreader")
local utilities = require("__load-spreader__/utilities")Iterates up to a specified limit on a table, passing each object to a processing function. This allows you to control how many items are processed per tick.
Parameters:
limit(integer) - Maximum number of items to process this tickobject_storage(table) - Table containing the objects to processcursors_storage(table) - Storage space for cursor state (should be fromstorage)storage_name(string) - Unique identifier for this cursor in the cursor storagefunc(function) - Function to call for each objectkwargs(table, optional) - Additional arguments to pass tofunc(Note:"object"and"key"are reserved)
Example:
-- In control.lua
local load_spreader = require("__load-spreader__/load_spreader")
-- Initialize storage
script.on_init(function()
storage.my_entities = {}
storage.cursors = {}
end)
-- Process entities
local function make_entity_operable(kwargs)
local entity = kwargs.object
local key = kwargs.key
local bonus_param = kwargs.bonus_param
-- Your processing logic here
if entity.valid then
-- Obviously, this is only an exemple, I expect you to use this
-- to do more complex stuff, like operations on inventories and such.
entity.operable(kwargs.is_operable)
else
storage.my_entities[key] = nil
end
end
script.on_event(defines.events.on_tick, function()
-- Process up to 50 entities per tick
load_spreader.process_up_to_limit(
50, -- limit
storage.my_entities, -- object_storage
storage.cursors, -- cursors_storage
"entity_processor", -- storage_name
make_entity_operable, -- func
{["is_operable"] = true} -- kwargs (optional)
)
end)Safely iterates to the next item in a table with stateful iteration and automatic wrap-around.
Parameters:
tbl(table) - The table to iterate overkey(any|nil) - Current cursor position (nil to start from beginning)
Returns:
next_key(any|nil) - The next key in the table, or nil if emptynext_value(any|nil) - The value associated with next_key, or nil if empty
Example:
local utilities = require("__load-spreader__/utilities")
local my_table = {a = 1, b = 2, c = 3}
local cursor = nil
-- First call
local cursor, value = utilities.select_next_item(my_table, cursor) -- Returns first item
-- Subsequent calls
local cursor, value = utilities.select_next_item(my_table, cursor) -- Next item
-- When reaching the end, automatically wraps to the beginning- Processing large entity lists: Spread entity updates across multiple ticks
- Complex calculations: Break up expensive operations into manageable chunks
- Periodic maintenance: Check and update game state without causing lag spikes
- Platform logistics: Evaluate platform requests incrementally (as used in Inter Platform Logistics)
Load Spreader uses a cursor system to remember where processing stopped in the previous tick. When called again, it resumes from that position and processes up to the specified limit. Once it reaches the end of the table, the cursor automatically wraps around to the beginning, creating a continuous processing cycle.
This ensures:
- Even distribution of processing load across ticks
- No items are skipped or processed twice consecutively
- Graceful handling of table modifications during iteration
- Factorio 2.0 or higher
- Base mod >= 2.0.69
- Discord: puke0417
- Community: Join our Discord
Author: SirPuck
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
You are free to:
- Share — copy and redistribute the material in any medium or format
- Adapt — remix, transform, and build upon the material
Under the following terms:
- Attribution — You must give appropriate credit to SirPuck, provide a link to the license, and indicate if changes were made
- NonCommercial — You may not use the material for commercial purposes
- ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license
Load Spreader was developed to handle performance optimization needs in Inter Platform Logistics and is provided as a general-purpose library for the Factorio modding community.