More Infinite Research


Productivity for intermediates, science packs, final products, spoilage rate, and modded recipes. Bonuses for player stats, robot specs, weapon speed, stack size, cargo landing pads, and more... Override game limits on productivity, efficiency, speed, quality, and recycling. Settings to disable, limit, and rebalance each added research. Designed for vanilla, Space Age, and overhaul mods.

Tweaks
5 hours ago
0.13 - 2.1
8.03K
Logistics Trains Combat Character Mining Fluids Logistic network Manufacturing Cheats

g Crash error

2 days ago

Error while running event more-infinite-research::on_init()
more-infinite-research/runtime/native_credits.lua:1050: MIR native family credit has invalid main or carrier [MIR-FAMILY-CREDIT family="research_processing_unit"; recipe="processing-unit"; force=1; expected_change=0.1; scope_valid=true; main_recipe_change=nil; main.id="recipe-prod-research_processing_unit-1"; main.name="recipe-prod-research_processing_unit-1"; main.level=1; main.researched=false; main.prototype_name="recipe-prod-research_processing_unit-1"; main.first=1; main.max=4294967295; main.hidden=true; main.enabled=true; main.visible_disabled=false; main.effects_type="table"; main.effects_count=0; positive.id="mir-native-credit-research_processing_unit-processing-unit-positive"; positive.name="mir-native-credit-research_processing_unit-processing-unit-positive"; positive.level=1; positive.researched=false; positive.prototype_name="mir-native-credit-research_processing_unit-processing-unit-positive"; positive.first=1; positive.max=4294967295; positive.hidden=true; positive.enabled=false; positive.visible_disabled=false; positive.effects_type="table"; positive.effects_count=2; positive.effect_type="change-recipe-productivity"; positive.recipe="processing-unit"; positive.change=0.1; negative.id="mir-native-credit-research_processing_unit-processing-unit-negative"; negative.name="mir-native-credit-research_processing_unit-processing-unit-negative"; negative.level=1; negative.researched=false; negative.prototype_name="mir-native-credit-research_processing_unit-processing-unit-negative"; negative.first=1; negative.max=4294967295; negative.hidden=true; negative.enabled=false; negative.visible_disabled=false; negative.effects_type="table"; negative.effects_count=2; negative.effect_type="change-recipe-productivity"; negative.recipe="processing-unit"; negative.change=-0.1]
stack traceback:
[C]: in function 'error'
more-infinite-research/runtime/native_credits.lua:417: in function 'family_observations'
more-infinite-research/runtime/native_credits.lua:819: in function 'preflight_family_transition'
more-infinite-research/runtime/native_credits.lua:1050: in function 'on_init'
more-infinite-research/runtime/bootstrap.lua:346: in function <more-infinite-research/runtime/bootstrap.lua:338>

2 days ago
(updated a day ago)

im fixed this with Gemini

a day ago
(updated a day ago)

If you can, mind sharing what fixes worked for you (here or via github) and ill incorporate them? Either way ill try and solve the problem for the next patch

a day ago
(updated a day ago)

Bug Report: MIR Crash on on_init() Caused by External Mods Mutating Hidden Carrier Technologies

1. Summary

In Factorio 2.1 / Space Age, More Infinite Research (e.g. version 5.0.21014) crashes during world initialization (on_init) when played alongside mods that iterate over data.raw.technology and inject extra productivity recipes without checking if a technology is hidden or internal.

This was observed with Cerys-Moon-of-Fulgora (and previously encountered with rigor-module before it was patched).


2. Exact Error & Stack Trace

Error while running event more-infinite-research::on_init()
__more-infinite-research__/runtime/native_credits.lua:1050: MIR native family credit has invalid main or carrier [MIR-FAMILY-CREDIT family="research_low_density_structure"; recipe="scrap-recycling"; force=1; expected_change=0.1; scope_valid=true; main_recipe_change=nil; main.id="recipe-prod-research_low_density_structure-1"; main.name="recipe-prod-research_low_density_structure-1"; main.level=1; main.researched=false; main.prototype_name="recipe-prod-research_low_density_structure-1"; main.first=1; main.max=4294967295; main.hidden=true; main.enabled=true; main.visible_disabled=false; main.effects_type="table"; main.effects_count=0; positive.id="mir-native-credit-research_low_density_structure-scrap-recycling-positive"; positive.name="mir-native-credit-research_low_density_structure-scrap-recycling-positive"; positive.level=1; positive.researched=false; positive.prototype_name="mir-native-credit-research_low_density_structure-scrap-recycling-positive"; positive.first=1; positive.max=4294967295; positive.hidden=true; positive.enabled=false; positive.visible_disabled=false; positive.effects_type="table"; positive.effects_count=2; positive.effect_type="change-recipe-productivity"; positive.recipe="scrap-recycling"; positive.change=0.1; negative.id="mir-native-credit-research_low_density_structure-scrap-recycling-negative"; negative.name="mir-native-credit-research_low_density_structure-scrap-recycling-negative"; negative.level=1; negative.researched=false; negative.prototype_name="mir-native-credit-research_low_density_structure-scrap-recycling-negative"; negative.first=1; negative.max=4294967295; negative.hidden=true; negative.enabled=false; negative.visible_disabled=false; negative.effects_type="table"; negative.effects_count=2; negative.effect_type="change-recipe-productivity"; negative.recipe="scrap-recycling"; negative.change=-0.1]
stack traceback:
    [C]: in function 'error'
    __more-infinite-research__/runtime/native_credits.lua:417: in function 'family_observations'
    __more-infinite-research__/runtime/native_credits.lua:819: in function 'preflight_family_transition'
    __more-infinite-research__/runtime/native_credits.lua:1050: in function 'on_init'
    __more-infinite-research__/runtime/bootstrap.lua:346: in function <__more-infinite-research__/runtime/bootstrap.lua:338>

Key detail from the error message: * positive.effects_count=2 * negative.effects_count=2


3. Root Cause Analysis

How More Infinite Research Works

In research/native_credit_definitions.lua, MIR creates internal carrier technologies: * positive_id = "mir-native-credit-" .. family .. "-" .. recipe .. "-positive" * negative_id = "mir-native-credit-" .. family .. "-" .. recipe .. "-negative"

These carriers are created with: * hidden = true * enabled = false * Exactly 1 effect in effects: {type = "change-recipe-productivity", recipe = recipe, change = change}.

At runtime (runtime/native_credits.lua), carrier_scalar inspects each carrier:

local function carrier_scalar(technology, descriptor, direction)
  local effects = carrier_effects(technology, descriptor, direction)
  if effects == nil or #effects ~= 1 or next(effects) ~= 1 or next(effects,1) ~= nil then return nil end
  ...

MIR expects #effects == 1. If #effects > 1, carrier_scalar returns nil, causing MIR to fall back to carrier_vector. carrier_vector then looks for a public reference technology matching the combined vector (e.g. scrap-recycling-productivity), which does not exist for arbitrary foreign recipe combinations, ultimately raising the unrecoverable error.

What Other Mods Do

In data-final-fixes.lua, certain mods iterate blindly across all technologies in data.raw.technology.

For example, in Cerys-Moon-of-Fulgora (prototypes/override-final/technology.lua):

for _, technology in pairs(data.raw.technology) do
    local processing_unit_productivity_change = 0
    local scrap_recycling_productivity_change = 0
    ...
    if technology.effects then
        for _, effect in ipairs(technology.effects) do
            if effect.type == "change-recipe-productivity" and effect.recipe == "scrap-recycling" then
                scrap_recycling_productivity_change = scrap_recycling_productivity_change + effect.change
            end
            ...
        end

        if scrap_recycling_productivity_change ~= 0 and cerys_scrap_productivity_change == 0 then
            table.insert(technology.effects, {
                type = "change-recipe-productivity",
                recipe = "cerys-nuclear-scrap-recycling",
                change = scrap_recycling_productivity_change
            })
        end
    end
end

Because Cerys does not check if technology.hidden, it injects "cerys-nuclear-scrap-recycling" directly into MIR's mir-native-credit-research_low_density_structure-scrap-recycling-positive and -negative carriers.

This changes #effects from 1 to 2, directly causing MIR to fail validation at runtime.

(A similar loop previously occurred in rigor-module, where it injected extra variants into all technology effects until fixed).


4. Proposed Solutions

Solution 1: Ordering dependency in info.json (For More Infinite Research)

Add content and planet mods running late data-final-fixes.lua scripts to dependencies with (?) in MIR's info.json:

"(?) Cerys-Moon-of-Fulgora"

When Cerys loads before MIR, MIR creates its carriers after Cerys's override-final/technology.lua has already finished executing, so the carriers remain untouched.

Solution 2: Carrier sanitization / self-defense in MIR (Recommended for MIR author)

In data-final-fixes.lua right before calling generator.install(technologies, data), or at the end of the data stage:
Strip any foreign-injected effects from technologies whose names match "^mir%-native%-credit%-", ensuring only the single original effect matching the carrier's target recipe is retained:

for _, technology in ipairs(technologies) do
  if technology.name and technology.name:find("^mir%-native%-credit%-") and technology.effects and #technology.effects > 1 then
    -- Retain only the intended primary effect for this carrier
    local primary_effect = technology.effects[1]
    technology.effects = { primary_effect }
  end
end

Alternatively, in runtime/native_credits.lua:
Have carrier_scalar filter and locate the specific effect matching descriptor.recipe rather than rejecting #effects ~= 1 if third-party mods appended extra effects.

Solution 3: Proper filtering in external mods (For Cerys / other mod authors)

Any mod that iterates over data.raw.technology to propagate recipe productivity must skip hidden and internal carrier technologies:

for _, technology in pairs(data.raw.technology) do
    if not technology.hidden 
       and technology.enabled ~= false 
       and not (technology.name and (technology.name:find("^mir%-") or technology.name:find("^recipe%-prod%-")))
       and technology.effects then
        -- proceed with effect propagation
    end
end

(This is the exact filter that rigor-module implemented in its data-final-fixes.lua line 712).

New response