Paintball¶
Paintball is available as a native two-variant PettingZoo family:
| Variant | Upstream alias | Goal |
|---|---|---|
capture_the_flag |
paintball__capture_the_flag |
Capture the opposing flag while defending your own. |
king_of_the_hill |
paintball__king_of_the_hill |
Paint and control the central hill. |
Both variants use eight agents split into red and blue teams, color-painting zaps, health, respawn, native RGB rendering, and optional global observations.
Screenshots¶
| Variant | Screenshot |
|---|---|
| Capture the Flag | ![]() |
| King of the Hill | ![]() |
API¶
See the generated Paintball API reference for signatures and public objects.
Use the family dispatcher:
from mp.paintball import env, parallel_env
parallel = parallel_env("capture_the_flag", render_mode="rgb_array")
aec = env("paintball__king_of_the_hill")
Or import a variant directly:
from mp.paintball.king_of_the_hill import (
PaintballKingOfTheHillConfig,
parallel_env,
)
config = PaintballKingOfTheHillConfig(observation_mode="global")
env = parallel_env(config=config)
Agents are named player_0 through player_7. Each infos[agent] includes
meltingpot_player_index and team.
Actions and observations¶
The action space is Discrete(9):
| Action | Meaning |
|---|---|
0 |
no-op |
1 |
forward |
2 |
backward |
3 |
step left |
4 |
step right |
5 |
turn left |
6 |
turn right |
7 |
primary zap |
8 |
secondary zap |
Default per-agent observations are:
| Key | Shape | Type |
|---|---|---|
RGB |
(88, 88, 3) |
uint8 |
READY_TO_SHOOT |
() |
float64 |
state() and render_mode="rgb_array" return the global world RGB frame with
shape (184, 184, 3). Pass observation_mode="global" to return that frame as
each agent's RGB observation.
Mechanics¶
Painted ground can trap opponents: avatars on enemy-colored ground cannot move until they repaint their current tile. Primary zaps are short and wide; secondary zaps are longer, narrow, and require standing still for one frame. Destroyable walls can be damaged by zaps and become passable rubble.
Capture the Flag gives +1 to the capturing team and -1 to the other team.
King of the Hill gives +1 per step to the controlling team and -1 per step
to the other team.
Reward strategy and failure modes¶
Capture the Flag rewards coordinated lanes: attackers paint safe routes toward the opposing flag while defenders repaint choke points and delay carriers. King of the Hill rewards durable area control, so teams should paint the hill, rotate low-health players out, and use secondary zaps to break entrenched opponents.
Bad equilibria include teams fixating on eliminations while ignoring the flag or hill, paint stalemates where both sides repaint the same corridor without advancing, and overextended solo attacks that feed respawn cycles. Because enemy paint blocks movement, one neglected tile can trap teammates and cascade into lost map control.
Playable notebooks¶
Launch a playable notebook with:
uv run marimo run notebooks/paintball/capture_the_flag_mo.py
uv run marimo run notebooks/paintball/king_of_the_hill_mo.py
Controls:
- WASD or arrow keys move the active player.
- Q/E turn the active player.
- SPACE fires the primary zap.
- F fires the secondary zap.
- TAB switches the controlled player.
- ESC closes the pygame window.

