factoriax.engine.constants#
Constants and enumerations for the Factoriax environment.
This module holds pure-Python definitions only. The JAX arrays that come from
them (the gather tables and the state-array dtypes) live in
factoriax.engine.tables.
The enum values here are a wire format.
factoriax.engine.levels.save_level() writes raw integers for terrain and
machine kinds into level JSON. The observation exposes the same integers to
trained policies, and the Action values are the output space of a
policy. A new number for an existing member therefore invalidates saved levels
and trained checkpoints. New members must go at the end of an enum, never in
the middle.
Module Attributes
Items with a |
|
the half-fabricates and the machines. |
|
every item type except |
|
Width of the item axis of every inventory array, |
|
Size of the discrete action space. |
|
Fixed width of the |
|
Units of ore that an ore tile holds when a level sets no count. |
|
First |
|
First |
|
First |
|
First |
|
Machine that each placeable item becomes on the map. |
|
Placeable item ids, the keys of |
|
the resources and the half-fabricates. |
|
Item that each ore block gives to the player who mines it. |
|
Science pack item ids that a |
|
Length of |
- class factoriax.engine.constants.Action(value)#
Action a player issues per step.
This enum comes from five blocks that follow each other, in this order:
MoveAction,InteractAction, thenPLACE_overPLACEMENT_ITEMS,CRAFT_overCRAFT_ITEMS, andDEPOSIT_overDEPOSIT_ITEMS.PLACE_BASE,CRAFT_BASE, andDEPOSIT_BASEgive the first value of each parametric block.The actions are compound. The item is part of the action name, so an agent needs no separate slot cursor and no item cursor. The action space stays flat.
WITHDRAWis the exception, because a machine exposes one output slot at a time and needs no item argument.This is the action space of a policy.
NUM_ACTIONSis its size. A trained checkpoint learned the integer values, so a new member in the middle invalidates every existing checkpoint.
- factoriax.engine.constants.BLOCK_MAX_RESOURCES = 30000#
Units of ore that an ore tile holds when a level sets no count. This value is also the divisor that normalizes
block_resourcesfor the observation, so a tile with more ore than this value normalizes to more than 1.0.EnvState.block_resourcesis int16, so this value must stay less than 32767.
- factoriax.engine.constants.BLOCK_TO_ITEM: dict[int, int] = {BlockType.IRON: ItemType.IRON_ORE, BlockType.COPPER: ItemType.COPPER_ORE, BlockType.COAL: ItemType.COAL, BlockType.TIN: ItemType.TIN_ORE, BlockType.SILICON: ItemType.SILICON, BlockType.LIMESTONE: ItemType.LIMESTONE}#
Item that each ore block gives to the player who mines it. The keys are the blocks that a player can mine. A block that is absent here gives nothing.
- class factoriax.engine.constants.BlockType(value)#
Terrain kind of one tile, stored in
EnvState.map.A tile carries exactly one block type.
INVALID = 0is a sentinel. The editor palette does not offer it, so a tile with this value shows that the map array is still full of zeros. The engine gives it no behavior of its own and treats it as walkable ground that no player can mine.OUT_OF_BOUNDSalso never occupies a stored tile. A query outside the map returns this value, and the observation padding fills the border with it. A policy can therefore see the edge of the map.WATERandOUT_OF_BOUNDSare the terrain that blocks movement.factoriax.engine.tables.SOLID_BLOCKSlists them.DIRTis plain walkable ground. Terrain is not the whole rule. A placed machine also blocks its own tile, for every machine kind exceptCONVEYOR_BELT.The other six members are ore tiles. They are the keys of
BLOCK_TO_ITEMand the only tiles that a player can mine.
- factoriax.engine.constants.CRAFT_ITEMS: tuple[HalfFabricate | Machine, ...] = (HalfFabricate.IRON_PLATE, HalfFabricate.COPPER_PLATE, HalfFabricate.TIN_PLATE, HalfFabricate.WAFER, HalfFabricate.FRAME, HalfFabricate.CIRCUIT, HalfFabricate.WIRE, HalfFabricate.MOTOR, HalfFabricate.SENSOR, HalfFabricate.TIER1_SCIENCE_PACK, HalfFabricate.TIER2_SCIENCE_PACK, HalfFabricate.REFRACTORY, HalfFabricate.HULL, HalfFabricate.ENGINE_UNIT, HalfFabricate.AVIONICS, HalfFabricate.ROCKET_CORE, HalfFabricate.TIER3_SCIENCE_PACK, Machine.MINER, Machine.PALLET, Machine.CONVEYOR_BELT, Machine.ASSEMBLER, Machine.ARM, Machine.ROCKET, Machine.FURNACE, Machine.SCIENCE_LAB, Machine.SPLITTER, Machine.CROSSING)#
the half-fabricates and the machines. A player mines a raw resource and never crafts one, and
EMPTYis not an item.- Type:
Items with a
CRAFT_action
- factoriax.engine.constants.DEPOSIT_ITEMS: tuple[Resource | HalfFabricate | Machine, ...] = (Resource.COAL, Resource.IRON_ORE, Resource.COPPER_ORE, Resource.TIN_ORE, Resource.SILICON, Resource.LIMESTONE, HalfFabricate.IRON_PLATE, HalfFabricate.COPPER_PLATE, HalfFabricate.TIN_PLATE, HalfFabricate.WAFER, HalfFabricate.FRAME, HalfFabricate.CIRCUIT, HalfFabricate.WIRE, HalfFabricate.MOTOR, HalfFabricate.SENSOR, HalfFabricate.TIER1_SCIENCE_PACK, HalfFabricate.TIER2_SCIENCE_PACK, HalfFabricate.REFRACTORY, HalfFabricate.HULL, HalfFabricate.ENGINE_UNIT, HalfFabricate.AVIONICS, HalfFabricate.ROCKET_CORE, HalfFabricate.TIER3_SCIENCE_PACK, Machine.MINER, Machine.PALLET, Machine.CONVEYOR_BELT, Machine.ASSEMBLER, Machine.ARM, Machine.ROCKET, Machine.FURNACE, Machine.SCIENCE_LAB, Machine.SPLITTER, Machine.CROSSING)#
every item type except
EMPTY.- Type:
Items with a
DEPOSIT_action
- class factoriax.engine.constants.Direction(value)#
Facing of a player or machine, in absolute map directions.
Grid coordinates run right and down from the top-left tile.
UPis therefore the-ydirection, which moves to a lower row number, andDOWNis+y. A facing is absolute. It is never relative to the direction that the entity itself points to.The values start at 1. Zero is not a member, but code that stores a direction uses zero for “no direction”.
factoriax.engine.tables.DIRECTIONSkeeps index 0 for a zero offset, andLevelleaves a machine direction at 0 until something sets it.
- class factoriax.engine.constants.HalfFabricate(value)#
Crafted item that a player cannot place on the map.
Every member is a recipe output. The members follow tech depth approximately, from smelted plates to rocket parts. The engine gives this order no meaning.
- factoriax.engine.constants.ITEM_TO_MACHINE = {ItemType.MINER: Machine.MINER, ItemType.PALLET: Machine.PALLET, ItemType.CONVEYOR_BELT: Machine.CONVEYOR_BELT, ItemType.ASSEMBLER: Machine.ASSEMBLER, ItemType.ARM: Machine.ARM, ItemType.ROCKET: Machine.ROCKET, ItemType.FURNACE: Machine.FURNACE, ItemType.SCIENCE_LAB: Machine.SCIENCE_LAB, ItemType.SPLITTER: Machine.SPLITTER, ItemType.CROSSING: Machine.CROSSING}#
Machine that each placeable item becomes on the map. An item that is absent here has no
PLACE_action. The pairs are one to one, sofactoriax.engine.tablesbuilds both the forward gather array and its inverse from this one dict. The two arrays therefore cannot disagree.
- class factoriax.engine.constants.InteractAction(value)#
Action on the tile in front of the player, with no item parameter.
This is the second block of
Action, at an offset oflen(MoveAction). Every member acts on the one tile in front of the player. The facing selects the target, not a coordinate argument.ROTATE_*sets a placed machine to an absoluteDirection. These four members must stay next to each other, inLEFT, RIGHT, UP, DOWNorder, because the dispatcher readsaction - ROTATE_BASEas an index.A member with no valid target does nothing, and this is not an error. The step uses one timestep and leaves the state unchanged.
- class factoriax.engine.constants.ItemType(value)#
Anything that can occupy an inventory slot.
This enum comes from the member names of
Resource,HalfFabricate, andMachine, in that order. TheNONEplaceholders drop out, andEMPTY = 0comes first.EMPTYmarks an unused slot, so a slot is empty by type, not by a zero count.Each value is the position of its name in that concatenation. A new member in an earlier category therefore moves every later item to a new value. This changes the item axis of
EnvState.player_inventoryand of the observation.Machineis the last category, so a new member there leaves every existing item value unchanged.
- factoriax.engine.constants.MAX_ACHIEVEMENTS = 64#
Fixed width of the
EnvState.achievements_unlockedbit vector. A scenario can define fewer achievements, and the unused bits at the end stay False. A larger value widens the observation and invalidates trained checkpoints.
- class factoriax.engine.constants.Machine(value)#
Placeable machine kind, and the entity tag that the engine stores per tile.
A machine is both an item and an entity. As an item, a player crafts it and carries it in the inventory. As an entity, it stands on a map tile. The member names compose
ItemTypeand thePLACE_,CRAFT_, andDEPOSIT_actions. The member values are whatEnvState.machine_typesandEnvState.ent_typehold.NONE = 0means no machine on the tile, the analog ofItemType.EMPTY = 0.The values index the per-machine rows of
factoriax.engine.tables.MACHINE_MAX_STACKand offactoriax.playground.editor.slot_display.MACHINE_SLOT_ROLESin the editor. Both tables walk this enum over a dict that has one key for each member. A new member with no entry in each dict therefore raisesKeyErrorat import.
- class factoriax.engine.constants.MoveAction(value)#
Action that moves the player or turns it in place.
This is the first block of
Action, at the same values. The directions are absolute map directions. They are not relative to the current facing.UPand the three other moves step one tile and also set the facing. TheFACE_*actions set the facing only, with no step. A move into a solid tile leaves the position unchanged and still sets the facing.
- factoriax.engine.constants.NUM_ACTIONS = 87#
Size of the discrete action space. Valid actions are
0toNUM_ACTIONS - 1.
- factoriax.engine.constants.NUM_ITEM_TYPES = 34#
Width of the item axis of every inventory array,
EMPTYincluded.
- factoriax.engine.constants.NUM_SCIENCE_PACK_TYPES: int = 3#
Length of
EnvState.science_consumed_step.
- factoriax.engine.constants.PLACEABLE_ITEM_LIST: tuple[int, ...] = (24, 25, 26, 27, 28, 29, 30, 31, 32, 33)#
Placeable item ids, the keys of
ITEM_TO_MACHINE. The order sets the palette order in the play UI and has no other meaning. An agent selects a placement by item identity.
- factoriax.engine.constants.PLACEMENT_ITEMS: tuple[Machine, ...] = (Machine.MINER, Machine.PALLET, Machine.CONVEYOR_BELT, Machine.ASSEMBLER, Machine.ARM, Machine.ROCKET, Machine.FURNACE, Machine.SCIENCE_LAB, Machine.SPLITTER, Machine.CROSSING)#
Items with a
PLACE_action, one for each placeable machine kind.
- factoriax.engine.constants.RESOURCE_ITEM_LIST: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23)#
the resources and the half-fabricates. This tuple is the complement of
PLACEABLE_ITEM_LISTover the item range, withoutEMPTY. The play UI reads it to divide the inventory display.- Type:
Item ids that no
PLACE_action can place
- factoriax.engine.constants.ROTATE_BASE: int = 13#
First
ROTATE_action value.action - ROTATE_BASEis an index in0..3intoLEFT, RIGHT, UP, DOWN, one less than theDirectionvalue.
- class factoriax.engine.constants.Resource(value)#
Raw material that a player gets from an ore tile.
There is one member for each ore
BlockType, andBLOCK_TO_ITEMholds the pairs. A resource is a recipe input only. No recipe makes one, and no action places one on the map.
- factoriax.engine.constants.SCIENCE_PACK_TYPES: tuple[int, ...] = (16, 17, 23)#
Science pack item ids that a
SCIENCE_LABconsumes, in tier order. The position of a pack here is its index into the per-step delta vectorEnvState.science_consumed_step. The order is therefore part of the state layout, and reward functions and analysis code read it.
- class factoriax.engine.constants.SlotRole(value)#
Purpose of one inventory slot on a machine.
factoriax.playground.editor.slot_display.MACHINE_SLOTSdeclares the roles for each machine kind. The role labels the slot for the editor and the play UI. The simulation stores the contents of a machine in its own entity arrays and never reads a role.NONEalso fillsfactoriax.playground.editor.slot_display.MACHINE_SLOT_ROLESto the width of the widest machine, so it marks a slot that does not exist. No machine in this repository declares aFUELslot. The editor still supports the role, which limits the slot to coal.