factoriax.engine.envs.common#

The shared six-patch geometry and state predicates of the 16x16 scenarios.

EasyRocket-v1 and the miner-curriculum scenarios share one world geometry: a 16x16 dirt map with six 2x2 ore patches that do not overlap, one for each ore block. A PRNG places them, and they stay clear of the centre spawn area and of the outer ring.

This module owns that geometry. It holds the sampling helpers that run on the host, and the jittable generator six_patch_terrain(). It also holds the pure-JAX state predicates that a scenario joins into an achievement condition. No scenario module therefore imports from another scenario module.

Module Attributes

VALID_PATCH_CORNERS

Every 2x2 patch corner inside the outer ring that does not touch the inner spawn zone or its ring.

factoriax.engine.envs.common.VALID_PATCH_CORNERS: ndarray = array([[ 1,  1],        [ 1,  2],        [ 1,  3],        [ 1,  4],        [ 1,  5],        [ 1,  6],        [ 1,  7],        [ 1,  8],        [ 1,  9],        [ 1, 10],        [ 1, 11],        [ 1, 12],        [ 1, 13],        [ 2,  1],        [ 2,  2],        [ 2,  3],        [ 2,  4],        [ 2,  5],        [ 2,  6],        [ 2,  7],        [ 2,  8],        [ 2,  9],        [ 2, 10],        [ 2, 11],        [ 2, 12],        [ 2, 13],        [ 3,  1],        [ 3,  2],        [ 3,  3],        [ 3,  4],        [ 3,  5],        [ 3,  6],        [ 3,  7],        [ 3,  8],        [ 3,  9],        [ 3, 10],        [ 3, 11],        [ 3, 12],        [ 3, 13],        [ 4,  1],        [ 4,  2],        [ 4,  3],        [ 4,  4],        [ 4,  5],        [ 4,  6],        [ 4,  7],        [ 4,  8],        [ 4,  9],        [ 4, 10],        [ 4, 11],        [ 4, 12],        [ 4, 13],        [ 5,  1],        [ 5,  2],        [ 5,  3],        [ 5,  4],        [ 5, 10],        [ 5, 11],        [ 5, 12],        [ 5, 13],        [ 6,  1],        [ 6,  2],        [ 6,  3],        [ 6,  4],        [ 6, 10],        [ 6, 11],        [ 6, 12],        [ 6, 13],        [ 7,  1],        [ 7,  2],        [ 7,  3],        [ 7,  4],        [ 7, 10],        [ 7, 11],        [ 7, 12],        [ 7, 13],        [ 8,  1],        [ 8,  2],        [ 8,  3],        [ 8,  4],        [ 8, 10],        [ 8, 11],        [ 8, 12],        [ 8, 13],        [ 9,  1],        [ 9,  2],        [ 9,  3],        [ 9,  4],        [ 9, 10],        [ 9, 11],        [ 9, 12],        [ 9, 13],        [10,  1],        [10,  2],        [10,  3],        [10,  4],        [10,  5],        [10,  6],        [10,  7],        [10,  8],        [10,  9],        [10, 10],        [10, 11],        [10, 12],        [10, 13],        [11,  1],        [11,  2],        [11,  3],        [11,  4],        [11,  5],        [11,  6],        [11,  7],        [11,  8],        [11,  9],        [11, 10],        [11, 11],        [11, 12],        [11, 13],        [12,  1],        [12,  2],        [12,  3],        [12,  4],        [12,  5],        [12,  6],        [12,  7],        [12,  8],        [12,  9],        [12, 10],        [12, 11],        [12, 12],        [12, 13],        [13,  1],        [13,  2],        [13,  3],        [13,  4],        [13,  5],        [13,  6],        [13,  7],        [13,  8],        [13,  9],        [13, 10],        [13, 11],        [13, 12],        [13, 13]], dtype=int32)#

Every 2x2 patch corner inside the outer ring that does not touch the inner spawn zone or its ring. This module computes the list one time. The JAX generator draws its patches from this fixed set, so its rules match the rules of the host sampler exactly.

factoriax.engine.envs.common.blocks_under_active_miners(state: EnvState) → tuple[Array, Array]#

Return the active-miner mask and the block under each entity slot.

Returns:

active_mask is True for a slot that holds an active miner. block_at_pos is the block on the (ent_y, ent_x) tile of the entity. The function clamps the indices, so a free slot stays safe under JIT.

Return type:

tuple[jax.Array, jax.Array]

factoriax.engine.envs.common.patch_touches_inner_zone(px: int, py: int) → bool#

Report whether a 2x2 patch lands on the spawn zone.

The zone covers the 2x2 spawn area and the one-cell ring around it, so a player never starts on ore.

Parameters:
  • px – Top-left corner of the patch.

  • py – Top-left corner of the patch.

factoriax.engine.envs.common.patches_overlap(a: tuple[int, int], b: tuple[int, int]) → bool#

Report whether two 2x2 patches share a tile.

factoriax.engine.envs.common.producing_miners(state: EnvState) → tuple[Array, Array]#

Return the producing-miner mask and the block under each entity slot.

This function is like blocks_under_active_miners(), but the mask also needs items in the output buffer. A slot therefore counts only after its miner mined ore, and not when a player only placed it on an ore tile.

factoriax.engine.envs.common.sample_patch_corner(key: Array, placed: list[tuple[int, int]]) → tuple[int, int]#

Draw one valid patch corner on the host that overlaps no other patch.

The function draws a corner and tests it. If the corner fails a test, the function draws again.

Parameters:
  • key – PRNG key for the draws.

  • placed – Corners that other patches already hold. The result overlaps none of them.

Raises:

RuntimeError – If MAX_SAMPLE_ATTEMPTS draws give no valid corner.

factoriax.engine.envs.common.six_patch_terrain(key: Array, params: EnvParams) → Array#

Build a dirt map with one 2x2 patch for each ore block, with no overlap.

The placement is jittable and vmappable. The function shuffles the valid corners, which already avoid the spawn zone, with key. It then takes the first len(PATCH_BLOCKS) corners that overlap no patch already placed. There are about 200 candidates and six patches, so this always succeeds and needs no branch for a failure.

Parameters:
  • key – PRNG key that decides the layout.

  • params – The function does not read this argument. It is present for the TerrainFn signature.