Deadlock's Stacking Beltboxes & Compact Loaders Continued


Community-maintained continuation of Deadlock's Stacking Beltboxes & Compact Loaders, updated for Factorio 2.1.

Content
9 days ago
2.1
463
Logistics

b fawogae stack destroyed when its prototype type changes

4 hours ago

Title:​ fawogae stack destroyed when its prototype type changes (regression in 7.0.8)

Version:​ deadlock-beltboxes-loaders-continued 7.0.8 (also present in 7.0.9 / main)

Issue:​ When another mod re-registers an item under a different prototype type during data-updates, the generated stack is destroyed at data-final-fixes.

Log:​

plaintext

DBL: Warning: Item "fawogae" appears to have been deleted since it was added to
the deferred item updates list, destroying its generated stack.
Cause:​ prototypes/create_stack.lua → update_stacked_item() checks only data.raw[item_type][item_name]. DeadlocksStackingForPyanadon registers fawogae with the default type "item", but pyalienlife does data.raw.item.fawogae = nil in data-updates and re-creates it as type = "module". So the lookup fails and the stack is destroyed.

In 7.0.7 the same branch only logged a warning and returned, leaving the stack intact — so this is a regression introduced by 7.0.8's fail-closed validation.

Suggested fix:​ before treating an item as deleted, scan all prototype types (or at least accept a type change) and keep/rebuild the stack with the resolved type; only destroy when the name is absent from every type category.

4 hours ago

Title
Stacked items are destroyed when another mod re-registers a prototype under a different
type (Py's fawogae: item → module)
Summary
A generated stacked item is destroyed whenever data.raw[item_type][item_name] is nil in
DBL.update_stacked_item(), even if the prototype still exists under a different
prototype type. fawogae (Pyanodon) hits this: pycoalprocessing defines it as
type = "item", then pyalienlife deletes that item and re-registers the name as
type = "module".
This is a regression: it worked in 7.0.7 and broke in 7.0.8. Still broken in 7.0.9.
Mods involved
Mod
Version
Role
deadlock-beltboxes-loaders-continued
7.0.8 (also 7.0.9 / current main)
where the bug is
DeadlocksStackingForPyanadon-continued
0.7.0
registers fawogae
pycoalprocessing
3.1.7
defines fawogae as item
pyalienlife
3.1.8
deletes the item, defines fawogae as module
Factorio 2.1.20.
Symptom
fawogae gets no stacked variant, while every other registered Py item does.
factorio-current.log shows:
Loading mod deadlock-beltboxes-loaders-continued 7.0.8 (data-final-fixes.lua)
DBL: Warning: Item "fawogae" appears to have been deleted since it was added
to the deferred item updates list, destroying its generated stack.
Loading mod pycoalprocessing 3.1.7 (data-final-fixes.lua)
There is no Refusing to stack ... message — nothing about spoilage. The stack is simply
destroyed.
Root cause
prototypes/create_stack.lua, DBL.update_stacked_item():
function DBL.update_stacked_item(item_name, item_type)
local stacked_item_name = string.format("deadlock-stack-%s", item_name)
if not data.raw[item_type][item_name] then
DBL.log_warning("Item \""..item_name.."\" appears to have been deleted since it was added to the deferred item updates list, destroying its generated stack.")
items_to_update[stacked_item_name] = nil
deadlock.destroy_stack(item_name) -- <-- destroys a stack whose source still exists
return false
end
7.0.7 used the exact same condition but only logged "skipping it" and returned, so the
already-generated stack survived. The 7.0.7 → 7.0.8 diff of this branch is:
if not data.raw[item_type][item_name] then
- DBL.log_warning("... appears to have been deleted ... skipping it.")
- return
+ DBL.log_warning("... appears to have been deleted ... destroying its generated stack.")
+ items_to_update[stacked_item_name] = nil
+ deadlock.destroy_stack(item_name)
+ return false
end
The guard only inspects the single item_type that was originally passed to
add_stack(). DeadlocksStackingForPyanadon-continued registers fawogae without a
type field, so add_stack falls back to "item".
The 7.0.8 changelog says:
Added fail-closed validation for trigger-based spoilage counts, including partial stacked
item stacks and source prototypes changed by other mods.
A prototype changing type is precisely a "source prototype changed by another mod", but the
implementation treats it as a deletion.
Exact sequence
1. pycoalprocessing (data.lua) — prototypes/items/items.lua:319: defines
fawogae as type = "item".
2. pyalienlife (data.lua) — prototypes/items/items.lua:8197: defines
fawogae as type = "module" (both prototypes coexist at this point).
3. DeadlocksStackingForPyanadon-continued (data.lua) — create_all calls
deadlock.add_stack("fawogae", ..., "item"); deadlock-stack-fawogae is generated and
queued in items_to_update with item_type = "item".
4. pyalienlife (data-updates.lua:60) — data.raw.item.fawogae = nil. The item
version is deleted; the module version still exists as data.raw.module.fawogae.
5. deadlock-beltboxes-loaders-continued (data-final-fixes.lua) —
deferred_stacked_item_updates() runs before pycoalprocessing's data-final-fixes.
data.raw["item"]["fawogae"] is nil → deadlock.destroy_stack("fawogae").
Load-order timeline taken from factorio-current.log (mods are shown in execution order):
1.421 Loading mod pycoalprocessing 3.1.7 (data.lua)
3.416 Loading mod pyalienlife 3.1.8 (data.lua)
3.785 Loading mod DeadlocksStackingForPyanadon-continued 0.7.0 (data.lua)
4.706 Loading mod pyalienlife 3.1.8 (data-updates.lua) <-- deletes data.raw.item.fawogae
5.449 Loading mod deadlock-beltboxes-loaders-continued 7.0.8 (data-final-fixes.lua)
5.466 DBL: Warning: ... "fawogae" ... destroying its generated stack.
Suggested fix
Resolve the name across all item prototype types before concluding the prototype is gone.
Only destroy the stack when the name no longer exists under any type. This is the patch
I tested locally; it restores stacking and keeps the 7.0.8 fail-closed behaviour for real
deletions:
-- Resolve the prototype's real current type before concluding it was deleted.
local function find_prototype_across_types(item_name)
for _, item_type in ipairs({
"item", "ammo", "armor", "blueprint", "blueprint-book", "capsule",
"copy-paste-tool", "deconstruction-item", "gun", "item-with-entity-data",
"item-with-inventory", "item-with-label", "item-with-tags", "module",
"rail-planner", "repair-tool", "selection-tool", "space-platform-starter-pack",
"spidertron-remote", "tool", "upgrade-item",
}) do
local prototypes = data.raw[item_type]
if prototypes and prototypes[item_name] then
return prototypes[item_name], item_type
end
end
return nil, nil
end

function DBL.update_stacked_item(item_name, item_type)
local stacked_item_name = string.format("deadlock-stack-%s", item_name)
if not data.raw[item_type][item_name] then
local resolved, resolved_type = find_prototype_across_types(item_name)
if not resolved then
DBL.log_warning("Item \""..item_name.."\" appears to have been deleted since it was added to the deferred item updates list, destroying its generated stack.")
items_to_update[stacked_item_name] = nil
deadlock.destroy_stack(item_name)
return false
end
DBL.log_warning(string.format(
"Item \"%s\" was re-registered as type \"%s\" after being registered as \"%s\"; keeping its generated stack.",
item_name, resolved_type, item_type
))
item_type = resolved_type
if items_to_update[stacked_item_name] then
items_to_update[stacked_item_name].item_type = resolved_type
end
end
...
With this patch the log line becomes:
DBL: Warning: Item "fawogae" was re-registered as type "module" after being
registered as "item"; keeping its generated stack.
and fawogae stacks normally again.
Optional secondary fix
DeadlocksStackingForPyanadon-continued could also declare the correct type for fawogae
in migrations/shared/pycoalprocessing.lua:
{item = "fawogae", iconName = "fawogae-icon", icon = nil, stage = 1, icon_size = 64, type = "module"},
That alone would sidestep the case for this one item, but the core-mod guard is the actual
defect: it affects any mod that re-registers a prototype under a different type.
Reproduction
1. Enable pycoalprocessing, pyalienlife, DeadlocksStackingForPyanadon-continued and
deadlock-beltboxes-loaders-continued 7.0.8 or 7.0.9.
2. Start Factorio (no save needed — this is a prototype/data-stage issue).
3. Open %APPDATA%\Factorio\factorio-current.log and search for fawogae.
4. In game, fawogae has no stacked variant. Downgrading to 7.0.7 makes it stack again.
Versions checked
- 7.0.7 — works
- 7.0.8 — broken
- 7.0.9 / current main (prototypes/create_stack.lua still has the destroy branch, no
cross-type resolution) — still broken

New response