Skip to content

SirPuck/load-spreader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Load Spreader

A Factorio library mod that provides utilities to spread processing tasks over multiple ticks, helping to maintain game performance when working with large datasets.

Table of Contents

Overview

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.

Installation

As a Dependency

Add Load Spreader as a dependency in your mod's info.json:

{
  "dependencies": ["base >= 2.0", "load-spreader >= 1.0.0"]
}

Usage in Your Mod

Require the library in your mod:

local load_spreader = require("__load-spreader__/load_spreader")
local utilities = require("__load-spreader__/utilities")

API Reference

load_spreader.process_up_to_limit()

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 tick
  • object_storage (table) - Table containing the objects to process
  • cursors_storage (table) - Storage space for cursor state (should be from storage)
  • storage_name (string) - Unique identifier for this cursor in the cursor storage
  • func (function) - Function to call for each object
  • kwargs (table, optional) - Additional arguments to pass to func (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)

utilities.select_next_item()

Safely iterates to the next item in a table with stateful iteration and automatic wrap-around.

Parameters:

  • tbl (table) - The table to iterate over
  • key (any|nil) - Current cursor position (nil to start from beginning)

Returns:

  • next_key (any|nil) - The next key in the table, or nil if empty
  • next_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

Use Cases

  • 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)

How It Works

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

Requirements

  • Factorio 2.0 or higher
  • Base mod >= 2.0.69

Support

Credits

Author: SirPuck

License

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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages