Files
SandTools/docs/PRODUCTION_LINES.md
DownloadPizza 64c6df119f islands: extract in-game names (Landmark -> Toponym), incl. Wunderinsel = Strudel
Definitive island prefab -> in-game name link: each island_* prefab has a child Landmark
GameObject (LandmarkBehaviour.name) = the Toponym key, localized via i2 Toponyms/<name>.
New bundle/extract_island_names.py -> extracted/island_names.json.

Key results: Demo_Wunderinsel=Strudel, Demo_Marktinsel=Segen, Gartenfreude=Insel St. Clemens,
DeusExMashineSmall=Rauchwolke, and island_Factorio = Sprengstofffabrik (the explosives
factory). The LittleFactory/LittleFactoryArmory prefabs are the Forts.

Updates docs/PRODUCTION_LINES.md with in-game names and corrects the earlier Sprengstofffabrik
note (it IS the explosives factory -> Factorio, not the Armory islands). Supersedes the
name-guesses (e.g. DeusExMashine is Rauchwolke, not Maschineninsel).
2026-06-11 20:03:12 +02:00

5.6 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 prefab In-game name (Toponym) Recipe conveyors placed
island_Factorio Sprengstofffabrik energyRods, 80mmT3Cannon, contactGrenades, armorPiercingRocket*
island_Kaiserplatz Kaiserplatz energyRods, 40mmT3Cannon
island_Demo_Wunderinsel Strudel 70mmT3Cannon
island_DeusExMashineSmall Rauchwolke computingModules, coralDust
island_testIsland, island_testIslandTramplers (test, no Landmark) the 4 base* conveyors (inv↔large test combos, incl. 1x wineBox → 1000x coinCrown)

In-game names come from each island prefab's child Landmark (LandmarkBehaviour.name) → i2 Toponyms/<name>; see bundle/extract_island_names.py / extracted/island_names.json.

Notes / corrections:

  • The Sprengstofffabrik (explosives factory) is literally island_Factorio — its in-game Landmark name is Sprengstofffabrik, and it makes the grenades + AP rockets + cannons. So the original "Sprengstofffabrik = explosives" intuition was right; it's just that the prefab is Factorio, not an …Armory island.
  • The island_LittleFactory01-03 / …Armory01-03 prefabs are actually the Forts in-game (Fort Istria/Arpad/Tarnopol and Fort Zimmer/Metternich/Starhemberg) and place no recipe conveyors.
  • * 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).