PettingZoo environment for Polytopia-style multi-agent reinforcement learning
Project description
Polyterra Environment
A PettingZoo-compatible reinforcement learning environment for The Battle of Polytopia.
Overview
This project provides a Python RL environment that communicates with a C# game engine via JSON subprocess. It supports multi-agent training with full game state observation and comprehensive action spaces.
Project Structure
polyterra-env/
├── polyterra-env-py/ # Python PettingZoo environment
│ ├── polyterra_env.py # Main environment class
│ ├── game_data_mappings.py # Game data index mappings
│ └── tests/ # Test suite
├── csharp-backend/ # C# game engine bridge
│ ├── PolyterraEnvBridge.cs # RL environment bridge
│ ├── Program.cs # Server entry point
│ └── *.cs # Supporting classes
├── polytopia-game-logic/ # Decompiled game logic (dependencies)
│ ├── GameLogicAssembly/ # Core game logic
│ └── PolytopiaBackendBase/ # Backend helpers
└── README.md # Documentation
Installation
Prerequisites
- Python 3.8+
- .NET 8.0 SDK
- PettingZoo, Gymnasium, NumPy
Setup
- Install Python dependencies:
cd polyterra-env-py
pip install pettingzoo gymnasium numpy
- Build C# backend:
cd csharp-backend
dotnet build
Usage
Basic Example
from polyterra_env import PolyterraEnv
import numpy as np
# Create environment
env = PolyterraEnv(
num_players=4,
game_mode="perfection",
max_turns=30,
render_mode="human"
)
# Reset environment
env.reset(seed=42)
# Game loop
for agent in env.agent_iter():
obs = env.observe(agent)
# Simple policy: end turn
action = np.array([0, 0, 0, 0, 0, 0]) # END_TURN
env.step(action)
if env.terminations[agent] or env.truncations[agent]:
break
env.close()
Logging Game States for Visualization
The environment doesn't include rendering to keep training fast. Instead, save interesting game states during training:
from polyterra_env import PolyterraEnv
env = PolyterraEnv(render_mode=None) # No rendering overhead
env.reset(seed=42)
# During training, save interesting moments
for agent in env.agent_iter():
obs = env.observe(agent)
action = policy(obs)
env.step(action)
# Save state when something interesting happens
if high_reward or novel_strategy:
state = env.get_state_snapshot()
save_to_file(state) # For later visualization
env.close()
See example_training_with_logging.py for a complete example.
Running Tests
cd polyterra-env-py/tests
python test_integration.py
python test_comprehensive_spaces.py
Environment Details
Observation Space
The observation is a Dict containing:
- Global State: turn, current_player_idx
- Player State: currency, score, tribe, cities, kills, technologies
- Map State: 256 tiles with terrain, improvements, units, visibility
- Units: List of own units with health, position, status
- Cities: List of own cities with level, population, production
- Opponents: Partial information (fog of war)
- Action Mask: Valid actions (10,000 possible)
Action Space
MultiDiscrete space with 6 components:
[action_type, target_x, target_y, unit_id_idx, param1, param2]
Supports 37 command types:
- 0: END_TURN
- 1: MOVE
- 2: ATTACK
- 3: BUILD
- 4: TRAIN
- 5: RESEARCH
- 6: UPGRADE
- 7-36: RECOVER, HEAL, PROMOTE, DISBAND, DESTROY, etc.
Game Modes
- Perfection: Score-based, 30 turns
- Domination: Last player standing
Features
- Multi-agent support (2-4 players)
- Fog of war (partial observability)
- Full game state access
- Parameterized action space
- Comprehensive observation space
- Turn-based gameplay
- Compatible with RL libraries (Stable-Baselines3, RLlib)
Architecture
The environment uses a client-server architecture:
- Python Environment (
polyterra_env.py) - PettingZoo interface - C# Backend (
PolyterraBackend) - Game engine and logic - JSON Protocol - Communication via subprocess stdin/stdout
The C# backend handles:
- Game state management
- Action validation
- Map generation
- Game rules enforcement
The Python environment handles:
- RL interface (observation/action spaces)
- Agent coordination
- Reward calculation
- Episode management
Development
Adding New Actions
- Add action type constant in
polyterra_env.py(line 62-77) - Implement conversion in
_action_to_command()(line 522+) - Update C# backend
HandleStep()to process new command
Modifying Observations
- Update
observation_space()definition (line 134+) - Modify
_parse_observation()to extract new fields (line 319+) - Update C# backend
GetObservation()to include new data
License
This project uses decompiled game logic from The Battle of Polytopia for educational and research purposes. All game assets and logic remain property of Midjiwan AB.
Credits
- Game: The Battle of Polytopia by Midjiwan AB
- Environment: PettingZoo framework
- Backend: .NET 8.0 with decompiled game logic
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file polyterra_env-0.1.0.tar.gz.
File metadata
- Download URL: polyterra_env-0.1.0.tar.gz
- Upload date:
- Size: 7.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff40543886a0b4f5d6d844bdd68d5c876588ce9b07a006abb1da247753fdce1d
|
|
| MD5 |
46d1d2d1a2ed3132dacd0e6bc061d1fc
|
|
| BLAKE2b-256 |
58ed649cd85a347589a027d0f3f088c2719a97e41035549bf3651c20c2e8e06a
|
File details
Details for the file polyterra_env-0.1.0-py3-none-any.whl.
File metadata
- Download URL: polyterra_env-0.1.0-py3-none-any.whl
- Upload date:
- Size: 6.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60850bc29ab2ca77dcb6ff5f22e921e7e42185d3a86c76039abc70855ea0702f
|
|
| MD5 |
636e68800fce2c2aa64d39b73bb6c237
|
|
| BLAKE2b-256 |
7010acd3854533a42033db0d8a6997d372723f8d6e905fdab549ae23d5c09930
|