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).
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 thebundles/symlink). - Prefabs:
game_conveyor_*_epb.prefab, underAssets/Content/Game/game_conveyor/.... 14 carry a recipe; 4 of them are namedgame_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 — aTransformand aMonoBehaviourwhose script isEntityBlueprint.EntityBlueprint : SerializedMonoBehaviour(Sirenix Odin), so the component data — including theCraftingRecipe— is in its Odin-serializedserializationData.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.SerializedBytes → bundle/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 isSprengstofffabrik, and it makes the grenades + AP rockets + cannons. So the original "Sprengstofffabrik = explosives" intuition was right; it's just that the prefab isFactorio, not an…Armoryisland. - The
island_LittleFactory01-03/…Armory01-03prefabs are actually the Forts in-game (Fort Istria/Arpad/Tarnopol and Fort Zimmer/Metternich/Starhemberg) and place no recipe conveyors. *Factorio's child is namedgame_conveyor_armorPiercingRocket(singular) while the recipe blueprint isgame_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 afterconveyor= generic infra;game_conveyor_<x>= recipe line).