Factory Commons¶
factory_commons/either_or is a native PettingZoo port of Melting Pot's
factory_commons__either_or substrate. Three players collect apples, move blue
cubes into factory hoppers, and choose between machines that preserve the blue
cube economy or convert cubes into short-term apple rewards.
Screenshot¶

API¶
See the generated Factory Commons API reference for signatures and public objects.
Use the family dispatcher:
from mp.factory_commons import env, parallel_env
parallel = parallel_env("either_or", render_mode="rgb_array")
aec = env("factory_commons__either_or")
Or import the variant directly:
from mp.factory_commons.either_or import FactoryCommonsEitherOrConfig, parallel_env
config = FactoryCommonsEitherOrConfig(observation_mode="global")
env = parallel_env(config=config)
Agents are named player_0, player_1, and player_2.
Actions and observations¶
The action space is Discrete(12):
| Action | Meaning |
|---|---|
0 |
no-op |
1 |
forward |
2 |
backward |
3 |
step left |
4 |
step right |
5 |
turn left |
6 |
turn right |
7 |
pickup |
8 |
grasp or drop |
9 |
hold |
10 |
hold and shove |
11 |
hold and pull |
With render_mode=None (the default), observations contain categorical grids;
render_mode="rgb_array" or "human" selects RGB observations.
observation_mode="local" (default), "global", and "focal" select the
upstream window, world-frame map, or whole-map agent-centered view in either
representation. See Structured observations
for grid keys, category IDs, and focal shapes.
Structured observations distinguish free, held, and in-flight objects in
FACTORY_OBJECTS, the two dispenser kinds in TERRAIN, movement freezes in
AVATAR_STATES, and visible stamina bars in AVATAR_STAMINA.
With a visual render mode and the default local view:
| Key | Shape | Type |
|---|---|---|
RGB |
(88, 88, 3) |
uint8 |
READY_TO_SHOOT |
() |
float64 |
STAMINA |
() |
float64 |
state() and render() with render_mode="rgb_array" return the global world
RGB frame with shape (128, 184, 3). In visual modes, pass
observation_mode="global" to return a global RGB observation for each agent.
Mechanics¶
Apples reward the entering avatar by +1 and then disappear into the wait
pool. Blue cubes can be grasped and dropped into open hoppers. The left
machines output a blue cube plus an apple, while the right machines output two
apples. Every grasp press picks up when empty-handed or drops when holding,
including consecutive presses. A held object retains its grasp marker in RGB.
Grappling actions use a short hold beam. A held avatar briefly cannot move or hold, and shove/pull moves that avatar if the destination is passable. Stamina falls with movement and recovers while resting; low stamina creates movement freezes.
Reward strategy and failure modes¶
Optimal long-run play balances immediate apples with keeping blue cubes in circulation. Dropping cubes into cube-preserving hoppers maintains future production, while two-apple machines can be useful when the cube stock is high or a player needs quick reward. Agents also need to budget stamina and use grappling to clear paths rather than grief productive carriers.
Bad equilibria include consuming the cube economy for short-term apples until few cubes remain, hoarding or blocking cubes near hoppers, and grappling loops where players shove each other instead of feeding machines. Stamina exhaustion can lock agents into slow, low-productivity movement if policies never rest.
Playable notebook¶
Launch the playable notebook with:
Controls:
- WASD or arrow keys move the active player.
- Q/E turn the active player.
- C sends the pickup action.
- SPACE grasps or drops objects.
- Shift holds another player.
- F shoves and R pulls a held player.
- TAB switches the controlled player.
- ESC closes the pygame window.