Files
SandTools/docs/PRODUCTION_LINES.md
DownloadPizza 8abe4bcecf production lines: resolve conveyor -> island placement mapping
The recipe conveyors (game_conveyor_<product>_epb) are placed as named child GameObjects
in the island_* prefabs (islands_assets_all.bundle), NOT via energy_grid (power grid only)
or any config asset. New extractor bundle/extract_conveyor_placements.py walks every island
prefab and cross-references production_lines.json -> extracted/conveyor_placements.json.

Result: Factorio (energyRods, 80mmT3Cannon, contactGrenades, armorPiercingRocket),
Kaiserplatz (energyRods, 40mmT3Cannon), Demo_Wunderinsel (70mmT3Cannon), DeusExMashineSmall
(computingModules, coralDust), testIsland(+Tramplers) (the 4 base test conveyors).

Corrects the earlier "Armory = Sprengstofffabrik hosts explosives" guess: the
LittleFactory/LittleFactoryArmory islands place NO recipe conveyors; grenades/rockets are
on Factorio. Unplaced blueprints: explosiveSmall, mechanicalParts (+ the plural
armorPiercingRockets, whose singular-named instance is on Factorio).
2026-06-11 19:38:13 +02:00

5.3 KiB

World factory "production lines" (conveyors) — where to find them

The game has fixed single-recipe world structures — item conveyors that run one recipe (e.g. 1 Raw Aurogen Crystal → 10 Energy Rods). These are a separate mechanic from the player workbench recipes (which live in extracted/crafting_recipes.json, sourced from CraftingRecipeBundle assets). This note records where they live so the data can be re-derived after a game update.

The mechanic

In code it's a "Factory Production Line". It's an Entitas ECS feature, namespace Hologryph.Sand.Shared.Game.Features.Crafting (see il2cpp/dump.cs):

Class Holds
ProductionLineComponent int inputEntityIndex, int outputEntityIndex
ProductionLineRecipeComponent CraftingRecipe recipe ← the recipe
ProductionLineInputDataComponent / …OutputDataComponent bool isLargeItem{Input,Output}
CraftingRecipe CraftingIngredient[] inputIngredients, CraftingIngredient[] outputIngredients, float craftingTimeSeconds
CraftingIngredient string itemId, int amount

Note CraftingRecipe / CraftingIngredient are the same types the workbench uses — only the container differs (a workbench holds List<CraftingRecipeBundle> recipeBundles; a production line holds a single CraftingRecipe on the entity).

Where the data lives

  • Bundle: epb_assets_all.bundle (reachable via the bundles/ symlink).
  • Prefabs: game_conveyor_*_epb.prefab, under Assets/Content/Game/game_conveyor/.... 14 carry a recipe; 4 of them are named game_conveyor_base* (large/small in→out variants) — what distinguishes them from the product-named ones beyond the name is not established here.
  • Serialization: each prefab GameObject (m_Name = game_conveyor_<x>_epb) has two components — a Transform and a MonoBehaviour whose script is EntityBlueprint. EntityBlueprint : SerializedMonoBehaviour (Sirenix Odin), so the component data — including the CraftingRecipe — is in its Odin-serialized serializationData.SerializedBytes, not in plain typetree fields. (Same situation as the loot tables — see TASK.md / extract_loot.py.)

Extraction path (how to read it)

UnityPy (with an IL2CPP TypeTreeGenerator over GameAssembly.dll + global-metadata.dat) reads the EntityBlueprint MonoBehaviour → pull serializationData.SerializedBytesbundle/odin_read.py parses the Odin binary → walk the tree for the node with inputIngredients / outputIngredients.

venv/bin/python bundle/extract_production_lines.py   # -> extracted/production_lines.json

Key item ids seen here: item_crystalHandles = Raw Aurogen Crystal, item_energyBar = NZ Mk2 Energy Rod, item_blackBox = Black Box, item_resourceCoralPiece = Coral Chunk. Resolve any id → display name via extracted/items_registry.json / extracted/item_names.json (built from CheatItemDefinitionsData).

Island placement — RESOLVED

Each recipe conveyor is placed as a named child GameObject (game_conveyor_<product>_epb) in the island_* prefab's Transform hierarchy inside islands_assets_all.bundle. It is NOT in the energy_grid_* blueprint (that holds only EnergyGridDataComponent — the power grid) and NOT in any config / designed-environment asset. Extract with:

venv/bin/python bundle/extract_conveyor_placements.py   # -> extracted/conveyor_placements.json

This walks every island prefab, collects the game_conveyor_<product> children (with local position) and cross-references each against production_lines.json. Result for this build:

Island Recipe conveyors placed
island_Factorio energyRods, 80mmT3Cannon, contactGrenades, armorPiercingRocket*
island_Kaiserplatz energyRods, 40mmT3Cannon
island_Demo_Wunderinsel 70mmT3Cannon
island_DeusExMashineSmall computingModules, coralDust
island_testIsland, island_testIslandTramplers the 4 base* conveyors (inv↔large test combos, incl. the 1x wineBox → 1000x coinCrown one)

Notes / corrections:

  • The earlier guess that the …Armory (Sprengstofffabrik) islands host the explosive / grenade / rocket conveyors is not supported by the placements: island_LittleFactory01-03 and island_LittleFactoryArmory01-03 exist (each has an energy_grid_*) but place no recipe conveyors at all. The grenade (contactGrenades) and rocket (armorPiercingRocket) lines are on Factorio. Factorio is the main multi-product factory here.
  • * Factorio's child is named game_conveyor_armorPiercingRocket (singular) while the recipe blueprint is game_conveyor_armorPiercingRockets (plural) — a name mismatch; same line (→ 3x item_rocketLauncherAmmoArmorPiercing).
  • Defined-but-unplaced recipe blueprints in this build: armorPiercingRockets (plural; the singular instance is on Factorio), explosiveSmall (→ 5x item_c4Dynamite), mechanicalParts (→ item_resourceMetal_t1).
  • Infrastructure conveyors (game_conveyorSlotInput, …OutInventory, …OutLargeItem, …InSwitch) accompany the recipe ones on each factory island — these are the input/output ports, not recipes (no underscore after conveyor = generic infra; game_conveyor_<x> = recipe line).