Skip to main content

AecEnvironment

Trait AecEnvironment 

Source
pub trait AecEnvironment {
    type AgentId: Eq + Hash + Clone + Send + Sync + 'static;
    type Observation: Clone + Send + Sync + 'static;
    type Action: Clone + Send + Sync + 'static;
    type Info: Default + Clone + Send + Sync + 'static;

    // Required methods
    fn possible_agents(&self) -> &[Self::AgentId];
    fn agents(&self) -> &[Self::AgentId];
    fn agent_selection(&self) -> &Self::AgentId;
    fn step(&mut self, action: Option<Self::Action>);
    fn reset(&mut self, seed: Option<u64>);
    fn observe(&self, agent: &Self::AgentId) -> Option<Self::Observation>;
    fn agent_state(
        &self,
        agent: &Self::AgentId,
    ) -> (f64, EpisodeStatus, Self::Info);
    fn sample_action(
        &self,
        agent: &Self::AgentId,
        rng: &mut impl Rng,
    ) -> Self::Action;

    // Provided methods
    fn last(
        &self,
    ) -> (Option<Self::Observation>, f64, EpisodeStatus, Self::Info) { ... }
    fn is_done(&self) -> bool { ... }
    fn num_agents(&self) -> usize { ... }
    fn max_num_agents(&self) -> usize { ... }
}
Expand description

A multi-agent environment with Agent Environment Cycle (turn-based) semantics.

Mirrors the semantics of PettingZoo’s AEC API, adapted for Rust’s type system. Use this when agents act one at a time — board games, card games, or any domain where simultaneous action is not meaningful.

§Design principles

  • Turn-based execution: one agent acts per step() call. agent_selection() identifies whose turn it is. After each call, the selection advances to the next active agent.

  • Persistent state: the environment tracks each agent’s most recent reward, status, and info as mutable state. Read it via agent_state() before deciding on an action. last() is a convenience that combines observe() and agent_state() for the current agent.

  • Cycling out terminated agents: when agent_state() reports a done status for agent_selection(), pass None to step() to advance the turn without applying an action. The type signature makes this contract explicit — passing Some(action) for a done agent is undefined behaviour.

  • Bevy-compatible by design: same Send + Sync + 'static bounds as ParallelEnvironment. The turn-based nature is inherently sequential, so ECS parallelisation applies less directly than with ParallelEnvironment.

  • No render(): visualisation is bevy-gym’s concern.

  • No close(): implement Drop if your environment holds resources.

§Example

Typical AEC loop:

env.reset(None);
while !env.is_done() {
    let (obs, _reward, status, _info) = env.last();
    let action = if status.is_done() {
        None  // cycle the terminated agent out
    } else {
        Some(policy.act(env.agent_selection(), &obs.unwrap()))
    };
    env.step(action);
}

Required Associated Types§

Source

type AgentId: Eq + Hash + Clone + Send + Sync + 'static

Identifier for each agent. Same semantics as ParallelEnvironment::AgentId.

Source

type Observation: Clone + Send + Sync + 'static

The observation type produced by observe().

Send + Sync + 'static are required for Bevy ECS compatibility.

Source

type Action: Clone + Send + Sync + 'static

The action type consumed by step().

Source

type Info: Default + Clone + Send + Sync + 'static

Auxiliary information returned alongside observations.

Use () if you don’t need it — Default is implemented for ().

Required Methods§

Source

fn possible_agents(&self) -> &[Self::AgentId]

The complete, fixed set of agent IDs for this environment.

Does not change between episodes or as agents terminate mid-episode.

Source

fn agents(&self) -> &[Self::AgentId]

The agents currently active in this episode.

Starts equal to possible_agents() after reset(). Shrinks as agents terminate or are truncated; never grows. Empty when the episode is over.

Source

fn agent_selection(&self) -> &Self::AgentId

The agent whose turn it currently is to act.

Source

fn step(&mut self, action: Option<Self::Action>)

Execute the current agent’s action and advance to the next agent.

Pass None when agent_state(agent_selection()) reports a done status, to cycle the agent out without applying an action. Pass Some(action) otherwise.

Source

fn reset(&mut self, seed: Option<u64>)

Reset the environment to an initial state, starting a new episode.

Unlike ParallelEnvironment::reset, this returns nothing. Retrieve initial observations via observe() after calling reset(). If seed is Some(u64), it is used to seed the internal RNG.

Source

fn observe(&self, agent: &Self::AgentId) -> Option<Self::Observation>

Retrieve the current observation for the given agent.

Returns None if the agent has terminated or been truncated — their last observation is no longer valid.

Source

fn agent_state(&self, agent: &Self::AgentId) -> (f64, EpisodeStatus, Self::Info)

Retrieve the persistent (reward, status, info) for the given agent.

This state is updated each time the agent acts and persists until its next turn. It reflects what the agent received as a result of its last action.

Source

fn sample_action( &self, agent: &Self::AgentId, rng: &mut impl Rng, ) -> Self::Action

Sample a random action for the given agent.

The rng is caller-supplied so exploration randomness can be seeded and tracked independently from environment randomness.

Provided Methods§

Source

fn last(&self) -> (Option<Self::Observation>, f64, EpisodeStatus, Self::Info)

Returns the full state for the currently selected agent.

Convenience wrapper around observe(agent_selection()) and agent_state(agent_selection()). This is the idiomatic way to read the current agent’s situation at the top of the AEC loop.

Source

fn is_done(&self) -> bool

Returns true when all agents have finished (active set is empty).

Source

fn num_agents(&self) -> usize

Number of currently active agents.

Source

fn max_num_agents(&self) -> usize

Maximum number of agents that could ever be active simultaneously.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§