Environment
- helmod 2.2.13 · Factorio 2.0.76 (Space Age)
- Custom overhaul mod (lead and springs)
Related: likely the same family as #366 (helmod losing output when a burner fuel shares identity with a block product), but a
distinct code path — #366 is fuel item == block output in a linked block; this is fuel burnt_result == the recipe's own
product, via a duplicate product append in getProducts.
Summary
When a recipe is crafted in a burner machine, helmod injects the fuel's burnt_result as an extra product in
model/RecipePrototype.lua, function RecipePrototype:getProducts (the ---insert burnt block, ~line 368):
table.insert(raw_products,
{ type = burnt_result.type, name = burnt_result.name, amount = fuel_count.count * factor,
catalyst_amount = fuel_count.count * factor }) -- net 0 (catalyst)
Crucially, this table.insert runs after getProducts has already flattened its de-duplication map (the map at lines ~296-332
that combines same-name products), so the burnt residue is appended without going through that dedup. If burnt_result.name is
the same item the recipe already produces, you get a second product entry for that item — a net-zero catalyst entry
alongside the real output. Downstream aggregation keys products by item name, so the net-0 entry collapses the real output:
the recipe shows zero net production of that item, and since it's consumed elsewhere in the block it flips to the
ingredient/input side.
Reproduction
- A burner assembling-machine whose fuel item has a burnt_result.
- A recipe crafted in that machine whose own product == that burnt_result.
- Observed: 0 net of that item; it appears as a block input instead of an output.
Proposed fix — merge the burnt residue into the existing same-named product instead of appending a duplicate:
local burnt_amount = fuel_count.count * factor
local merged = false
for _, p in pairs(raw_products) do
if p.name == burnt_result.name and (p.type or "item") == burnt_result.type then
p.amount = (p.amount or 0) + burnt_amount
p.catalyst_amount = (p.catalyst_amount or 0) + burnt_amount
merged = true
break
end
end
if not merged then
table.insert(raw_products, { type = burnt_result.type, name = burnt_result.name,
amount = burnt_amount, catalyst_amount = burnt_amount })
end
This preserves the real product's net output (amount - catalyst_amount) and also keeps catalyst_amount (which the existing
dedup map at line ~307 drops). The normal case (burnt_result ≠ any recipe product) is unchanged. Verified in-game: with the
merge the recipe shows correct net output; without it, zero.
Environment
Related: likely the same family as #366 (helmod losing output when a burner fuel shares identity with a block product), but a
distinct code path — #366 is fuel item == block output in a linked block; this is fuel burnt_result == the recipe's own
product, via a duplicate product append in getProducts.
Summary
When a recipe is crafted in a burner machine, helmod injects the fuel's burnt_result as an extra product in
model/RecipePrototype.lua, function RecipePrototype:getProducts (the ---insert burnt block, ~line 368):
table.insert(raw_products,
{ type = burnt_result.type, name = burnt_result.name, amount = fuel_count.count * factor,
catalyst_amount = fuel_count.count * factor }) -- net 0 (catalyst)
Crucially, this table.insert runs after getProducts has already flattened its de-duplication map (the map at lines ~296-332
that combines same-name products), so the burnt residue is appended without going through that dedup. If burnt_result.name is
the same item the recipe already produces, you get a second product entry for that item — a net-zero catalyst entry
alongside the real output. Downstream aggregation keys products by item name, so the net-0 entry collapses the real output:
the recipe shows zero net production of that item, and since it's consumed elsewhere in the block it flips to the
ingredient/input side.
Reproduction
Proposed fix — merge the burnt residue into the existing same-named product instead of appending a duplicate:
This preserves the real product's net output (amount - catalyst_amount) and also keeps catalyst_amount (which the existing
dedup map at line ~307 drops). The normal case (burnt_result ≠ any recipe product) is unchanged. Verified in-game: with the
merge the recipe shows correct net output; without it, zero.