HeroicLibrary


A library mod for heroic mods

Internal
6 days ago
2.0 - 2.1
270

Changelog

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.