# 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 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__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](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.SerializedBytes` → `bundle/odin_read.py` parses the Odin binary → walk the tree for the node with `inputIngredients` / `outputIngredients`. ```bash 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__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: ```bash venv/bin/python bundle/extract_conveyor_placements.py # -> extracted/conveyor_placements.json ``` This walks every island prefab, collects the `game_conveyor_` 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_` = recipe line).