Fruit Market¶
fruit_market/concentric_rivers is a native PettingZoo port of Melting Pot's
fruit_market__concentric_rivers substrate. Sixteen players harvest apples
and bananas, eat fruit for role-dependent rewards, manage hunger and stamina,
and trade fruit with nearby partners.
Screenshot¶

API¶
See the generated Fruit Market API reference for signatures and public objects.
Use the family dispatcher:
from mp.fruit_market import env, parallel_env
parallel = parallel_env("concentric_rivers", render_mode="rgb_array")
aec = env("fruit_market__concentric_rivers")
Or import the variant directly:
from mp.fruit_market.concentric_rivers import (
FruitMarketConcentricRiversConfig,
parallel_env,
)
config = FruitMarketConcentricRiversConfig(observation_mode="global")
env = parallel_env(config=config)
Agents are named player_0 through player_15.
Actions and observations¶
The action space is Discrete(25). Actions 0 through 12 are no-op,
movement, turning, eating, grappling, and offer cancellation; actions 13
through 24 are the valid apple/banana offer pairs.
Default per-agent observations are:
| Key | Shape | Type |
|---|---|---|
RGB |
(88, 88, 3) |
uint8 |
READY_TO_SHOOT |
() |
float64 |
STAMINA |
() |
float64 |
INVENTORY |
(2,) |
int64 |
MY_OFFER |
(2,) |
int64 |
OFFERS |
(102,) |
int64 |
HUNGER |
() |
float64 |
state() and render_mode="rgb_array" return the global world RGB frame with
shape (248, 248, 3). Pass observation_mode="global" to return a global RGB
observation for each agent.
Mechanics¶
Apple farmers harvest apples reliably but value bananas more; banana farmers harvest bananas reliably but value apples more. Trees become unripe after a successful harvest and regrow after 50 frames. Eating fruit resets hunger.
Offers use positive quantities for fruit requested and negative quantities for
fruit given. Nearby compatible public offers within radius 4 trade the minimal
matching quantities and clear both offers. Invalid offers, including offers
the player cannot afford, are hidden from MY_OFFER and OFFERS.
Movement, rivers, and hunger affect stamina. Low stamina can briefly freeze movement. Hold, shove, and pull use a short grappling beam.
Reward strategy and failure modes¶
The highest rewards come from specialization plus trade. Apple farmers should harvest apples and trade for bananas they value more; banana farmers should do the reverse. Good policies maintain affordable public offers, stay within trade radius of compatible partners, eat before hunger becomes costly, and avoid exhausting stamina in river crossings.
Bad equilibria include autarky, where each role eats only its own low-value fruit; offer spam with unaffordable or incompatible trades; and market freezes where players wait near partners but never post matching quantities. Grappling or river congestion can also create local monopolies that stop fruit from moving between roles.
Playable notebook¶
Launch the playable notebook with:
Controls:
- WASD or arrow keys move the active player.
- Q/E turn the active player.
- C/V eat an apple or banana.
- Shift holds another player.
- F shoves and R pulls a held player.
- X or Backspace cancels the current offer.
- 1-6 choose common offer presets.
- TAB switches the controlled player.
- ESC closes the pygame window.