Lua libraries for use by other mods and submods that are parts of a larger mod.
Version: 2.5.2
Date: 2026-07-24
Bugfixes:
- work_queue.lua: WorkQueue:dequeue now ignores a nil id instead of crashing. Assigning to a
table with a nil key (t[nil] = nil) is a hard error in Lua, so dequeue(nil) took the whole mod
down. It is now symmetric with enqueue, which already guarded nil. This fixed a non-recoverable
crash in Automatic Quality Upgrades when mining an entity with no unit_number (e.g. Gleba
plants/rocks) that matched the watch-type filter.
Version: 2.5.1
Date: 2026-07-21
Bugfixes:
- recipe.lua: Recipe.molten_resolver no longer explodes the distinct-fluid count of composite
items. Every existing casting recipe (vanilla or modded, molten or not, including multi-product
caster/ladle recipes) is now registered as its output's casting source, so a castable item
resolves to its own casting recipe's few fluids instead of decomposing through its crafting
recipe and unioning the whole sub-tree's fluids. Decomposition of items with no casting recipe
now prefers the producer with the FEWEST distinct fluids (was: most), to fit fluid-port limits.
- Added Recipe.primary_item_products (main_product-aware, skips probabilistic byproducts), used
for the widened casting-source/maker registration.
Changes:
- entity_prototype.lua: added EntityPrototype:order_fluidboxes_by_face(), which reorders a
crafting machine's recipe fluid_boxes so the largest single-face group of ports comes first
(used by the Casting Mixer so few-fluid recipes stay on one face).
Version: 2.5.0
Date: 2026-07-20
Changes:
- recipe.lua: Recipe.molten_resolver's cost() now returns a full Recipe.Cost table
({fluids=, items=, time=}) instead of a bare fluid list. BREAKING for callers of cost().
Ingredients that cannot be reduced to a fluid are carried through as `items` residue rather
than silently dropped, and `time` sums the crafting time of the whole substituted chain.
- recipe.lua: casting sources are no longer restricted to `molten-` fluids — any recipe
producing a single item from a fluid qualifies (holmium plate from holmium solution, concrete
from water). The chosen source records `molten` so callers can still tell the two apart.
- recipe.lua: maker[item] is now the list of every recipe producing the item, and the resolver
tries all of them. Previously only the alphabetically-first was tried, which dead-ended items
whose earliest-sorting producer had no path to a fluid.
- recipe.lua: a result computed under a cycle break is no longer memoized as if complete.
- recipe.lua: added Recipe.energy_required (defaults to the prototype default of 0.5).
- entity_prototype.lua: added EntityPrototype:order_fluidboxes_by_face — reorder a machine's
fluid_boxes so the largest group of connections sharing a face comes first, controlling which
ports a recipe's fluid ingredients bind to.
Version: 2.4.0
Date: 2026-07-19
Changes:
- recipe.lua: added Recipe.clamp_amounts — round/clamp a recipe ingredient list in place (item
counts to integer [1, 2^16-1], fluid amounts to a small positive minimum).
- technology.lua: added Tech.mirror_recipe_unlocks (copy a recipe's tech unlocks onto a derived
recipe), Tech.remove_recipe_unlocks (strip unlock-recipe effects for a recipe), and
Tech.create_recipe_unlock_technology (build a technology unlocking a list of recipes, with
prerequisite-derived cost and an icon fallback).
- sprites.lua: added Sprites.first_icon — reuse the first available icon/icons from a list of
prototypes (avoids shipping new art or referencing a missing icon path).
- entity_prototype.lua: added EntityPrototype:set_fluidboxes_input_only — rewrite a cloned
crafting machine's fluidboxes to input-only, for building multi-fluid input casters.
Version: 2.3.0
Date: 2026-07-19
Changes:
- recipe.lua: Recipe.products now includes an `amount` field per product (mean of an
amount_min/amount_max range when no fixed amount is given). Purely additive; existing callers
that read only type/name are unaffected.
- recipe.lua: added Recipe.is_molten_ingredient, Recipe.merge_ingredients, and
Recipe.molten_resolver — a data-stage resolver that derives, per item, the molten-fluid cost
of casting it from the real casting recipes present in data.raw (preferring vanilla casting
recipes, recursing composite items, memoized, cycle-safe). Consolidates the logic AllCastingRecipes
previously implemented inline.
- technology.lua: added Tech.techs_unlocking_recipe(recipe_name), a by-recipe reverse index of
the technologies that unlock a recipe (complements the by-product Tech.recipe_unlockers).
Version: 2.2.0
Date: 2026-07-16
Changes:
- EntityRegistry.new now accepts a list of entity types, or a function returning one, in
addition to a single type string. The function form is resolved on every scan_all() rather
than at handle construction, so a registry can track a type list driven by a runtime setting
without being rebuilt when that setting changes. Passing a single string behaves exactly as
before.
- EntityRegistry.new gained opts.include_ghosts (default false): when set, scan_all() also
registers entity ghosts of the tracked types, so a registry can track planned entities
alongside built ones.
- EntityRegistry:scan_all() now registers nothing when the tracked type list is empty, rather
than passing an empty filter to find_entities_filtered where it risks matching every entity.
Version: 2.1.1
Date: 2026-07-16
Bugfixes:
- Restored recipe.lua, which 2.1.0 dropped as "unused". It is required by the library's own
data.lua and technology.lua, so 2.1.0 failed to load at the data stage and took every
dependent mod down with it. It is also required by HeroicTechDependencies.
- sprites.lua returned the module wrapped in a table ({Sprites}) rather than the module, so
require("__heroic-library__.sprites") gave back a table whose functions were all nil. This
broke Sprites.add_icon/get_tech for entity_prototype, utilities and HeroicRoboports.
Version: 2.1.0
Date: 2026-07-15
Changes:
- Added quality module: deterministic data-stage enumeration of quality prototypes
(ordered/base_name/each, sorted by (level, name), hidden qualities skipped), control-stage
accessors (name_of/level_of/is_base), and pure naming helpers (variant_name/is_variant_of/
quality_of) for prototype-per-quality "variant" families.
- Added build_events module: reusable build/removal event wiring. on_built assembles the build
event list (feature-detecting Space Age on_space_platform_built_entity), registers per-event
entity+ghost filters, optionally wires on_entity_cloned, and routes real vs ghost entities to
separate callbacks. on_removed does the same for mined/died/destroyed events.
- Entity:replace and Entity:replace_ghost now also preserve the entity's direction (no-op for
directionless entities such as roboports and cargo bays; required for directional entities).
- Added Entity:normalize_ghost(base_name): collapse a variant ghost back to a base prototype
(used to re-derive prototype variants from blueprints on rebuild).
- Added offsets module: Offsets.ring(count, min, max) generates count points evenly spread
around a ring with radius alternating min/max (deterministic, data-stage safe) for laying out
repeated sub-features like charging pads and cargo hatches.
Version: 2.0.0
Date: 2026-07-05
Major Features:
- Added Entity: an OOP wrapper class over LuaEntity (control stage) with curated methods
(is_valid, assert_valid, is_ghost, is_type, is_name, replace, replace_ghost, unwrap) and
transparent read/write pass-through to the underlying LuaEntity. Transient handle only -
never store an Entity in storage.
- Added EntityPrototype: an OOP wrapper class over data.raw entity prototypes (data stage)
with flag helpers, minable helpers, next_upgrade/fast_replaceable_group pairing, icon
overlay, deterministic find/each lookup, and copy.
Changes:
- BREAKING: removed the entities module. Migrate as follows:
entities.is_valid(e) -> Entity.new(e):is_valid() (now a predicate; see Bugfixes),
entities.is_ghost(e) -> Entity.new(e):is_ghost(),
entities.is_type(e, t) -> Entity.new(e):is_type(t),
entities.replace(e, name, opts) -> Entity.new(e):replace(name, opts) (returns Entity),
entities.replace_ghost(g, name, opts) -> Entity.new(g):replace_ghost(name, opts).
Bugfixes:
- Validity checking is now a true predicate. The old entities.is_valid threw an error on
invalid/nil entities even though every known caller used it as an if-guard; Entity:is_valid
returns false instead. Use Entity:assert_valid for the old throwing behavior.
Version: 1.6.0
Date: 2026-07-04
Changes:
- Added table.sorted_pairs: deterministic (sorted-key) iteration for data-stage data.raw traversal.
- Added Recipe module: normalized 2.0 accessors (ingredients/products/enabled/recycling) with
defensive legacy result/normal handling.
- Added Tech tech-graph helpers: transitive_prerequisites, reaches, add_prerequisite_safe
(cycle- and redundancy-guarded), and recipe_unlockers (item/fluid -> unlocking techs index).
- Added Tech.force_research: guarded runtime unlock of a technology.
Version: 1.5.0
Date: 2026-07-02
Changes:
- Updated for Factorio 2.1 (now requires base >= 2.1).
- Added EntityRegistry: a storage-backed registry that tracks all entities of a type across surfaces.
- Added WorkQueue: a throttled nth-tick batch processor for spreading per-item work over ticks.
- Added modules helper: data-stage detection of per-line module tier counts, with mod overrides.
- Added entities.replace and entities.replace_ghost: nil-guarded fast-replace preserving energy/quality.
- Added Energy:scaled(multiplier, modifier) for tiered energy scaling.
Bugfixes:
- Fixed settings manager crashing when defining a runtime-global or per-user setting from a
settings.lua that is also required in the data/control stage. GlobalSettings and
UserSettings now only register the prototype during the settings stage and build an
accessor container otherwise.
Version: 1.2.0
Date: 2025-07-18
Changes:
- Added methods to check if an entity is of a specific type, including ghosts.
- Added and updated methods for finding entities and items. And also finding items inside entities.
Version: 1.1.0
Date: 2024-03-11
Changes:
- Added a item-group for heroic mods.
- Added various helper functions for heroic mods.
Version: 1.0.4
Date: 2024-03-11
Changes:
- Added helper methods for technologies and entities.
Version: 1.0.2
Date: 2024-05-11
Changes:
- Added String functions for my other mods.
Version: 1.0.1
Date: 2024-03-11
Changes:
- Added a debug print option.
Version: 1.0.0
Date: 2024-03-11
Changes:
- Published the mod.