AEC Loop¶
Both Gwent wrappers are PettingZoo AEC environments. AEC means only one agent is selected to act at a time, and trainers advance the game by repeatedly reading the active agent and submitting one action.
Standard Loop¶
Use env(...) for trainer integrations that should get PettingZoo's standard
out-of-bounds and order-enforcing wrappers:
from gwent.rl.pettingzoo import env
game = env(seed=123)
game.reset()
for agent in game.agent_iter():
observation, reward, termination, truncation, info = game.last()
if termination or truncation:
action = None
else:
mask = observation["action_mask"]
action = int(mask.nonzero()[0][0])
game.step(action)
Use raw_env(...) when tests or debugging need direct access to Gwent-specific
diagnostic properties such as core_state, rng, observation_feature_names,
selected_decks, or drafts.
Turn Selection¶
agent_selection is derived from the core engine:
- If a pending choice exists, the pending-choice player acts.
- Otherwise the current
active_playeracts. - In the deckbuilding meta environment, the active builder acts until both decks are selected and an inner match environment starts.
Non-active agents still have observations, but their action_mask is all
zeros and infos[agent]["legal_action_ids"] is empty.
Dead Steps¶
When an agent is terminated or truncated, call step(None) as PettingZoo
expects. The wrapped env(...) form enforces order and bounds before actions
reach the raw environment. The raw environment delegates dead-step handling to
PettingZoo's AEC base helpers.
Masks And Infos¶
Every observation is a dictionary:
For the selected live agent, action_mask.nonzero() matches
infos[agent]["legal_action_ids"]. For all other agents, the mask is empty.
Illegal live actions fail loudly instead of silently ending the match.