Project Overview¶
Purpose¶
The Predator-Prey Archetype Gridworld is a discrete, deterministic multi-agent reinforcement learning (MARL) environment built as a controlled research testbed. Its primary purpose is to enable mechanistic study of coordination, pursuit-evasion, and emergent behavior in multi-agent settings without the confounding variables present in more complex simulators.
Research Goals¶
| Goal | Description |
|---|---|
| Reproducibility | All experiments are fully seeded and config-driven. Two runs with the same seed and config produce identical trajectories. |
| Interpretability | State and action spaces are small and enumerable. Every transition can be traced manually. |
| Modularity | Observation models, reward structures, and learning algorithms are independently swappable via YAML config—no code changes required. |
| Educability | The codebase is structured to teach students the separation between environment dynamics, perception, incentives, and learning. |
Scope¶
In scope: - Discrete grid-based multi-agent dynamics - Configurable predator and prey teams - Pluggable observation, reward, and action-space systems - Per-agent speed/stamina mechanics via wrappers - Tabular Q-learning baselines (IQL, CQL, MixedTrainer) and PyTorch baselines: DQN (including Double DQN and Dueling DQN), ActorCritic, A2C, and A3C - Pygame-based visualization
Out of scope: - Continuous state/action spaces - Advanced policy-gradient methods (PPO, SAC, MADDPG) — though on-policy actor-critic baselines (ActorCritic, A2C, A3C) do ship - Networked or distributed training - Photorealistic rendering
System at a Glance¶
┌─────────────────────────────────────────────────────────┐
│ YAML Configuration │
│ env.yaml agents.yaml observations.yaml │
│ rewards.yaml actions.yaml experiment.yaml │
└────────────────────────┬────────────────────────────────┘
│ parsed by run_from_config.py
▼
┌─────────────────────────────────────────────────────────┐
│ Environment Layer │
│ GridWorldEnv ←→ Agent (×N) │
│ (core/ — immutable) │
│ │
│ ┌────────────┐ ┌────────────┐ ┌───────────────────┐ │
│ │Observations│ │ Rewards │ │ Action Spaces │ │
│ │(5 builders)│ │(3 funcs) │ │(3 spaces) │ │
│ └────────────┘ └────────────┘ └───────────────────┘ │
│ ↓ wrapped by SpeedWrapper (speed/stamina) │
└────────────────────────┬────────────────────────────────┘
│ env.step() / env.reset()
▼
┌─────────────────────────────────────────────────────────┐
│ Baselines Layer │
│ IQL (tabular) CQL (tabular, centralized) │
│ MixedTrainer (per-team) DQN (PyTorch, +Double/Dueling)│
│ ActorCritic A2C A3C (PyTorch, on-policy) │
│ (ppage/baselines/ — extensible) │
└─────────────────────────────────────────────────────────┘
Key Design Invariants¶
-
core/is immutable.gridworld.pyandagent.pyare never modified by contributors. All variation comes through configuration and plugins. -
All randomness is seeded. The environment uses
np.random.default_rng(seed)exclusively. No global random state. -
Plugins are self-contained. Observation builders and reward functions are pure-ish: they read env state but do not modify it.
-
Config drives everything. If something cannot be expressed in YAML, it should probably be a new plugin, not a code change.