Skip to main content

CodePraxis Football

Write a Python agent that plays football. Test it on your laptop, watch it play, record videos, and score it the same way the judges do.

Install

pip install codepraxis-football        # Python 3.12 or newer; Mac, Linux, Windows
codepraxis-football doctor             # checks the engine, rendering and video
codepraxis-football init my-agent      # sample agent + this guide + a practice level
cd my-agent

On a Linux server or a minimal Linux install, the game needs the system OpenGL libraries: sudo apt install libgl1 libegl1 (desktops already have them). No GPU is needed.

Try it

codepraxis-football play shoot_keeper                    # play it yourself with the keyboard
codepraxis-football watch agent.py shoot_keeper          # watch your agent in a window
codepraxis-football eval agent.py shoot_keeper           # official score: 100 seeded episodes
codepraxis-football video agent.py shoot_keeper -o a.mp4 # record without a window
codepraxis-football watch-match agent.py random match_5v5 # two agents live: yellow vs blue
codepraxis-football match agent.py other.py match_5v5    # same, no window, JSON result
codepraxis-football levels                               # every level

The window and videos hold the picture for a moment after goals, cards and set pieces. Add --fast to skip that. Training and eval never pause. The 3D view (window, video --view 3d) runs extra engine code that changes how a match plays out, so the same seed can end differently there than in eval. video --view topdown shows exactly what eval scored.

Keyboard: arrows move, hold e sprint, hold c dribble, s short pass, a high pass, w long pass, d shoot, x slide tackle, Esc quit.

Write an agent

An agent is a file with one function. It gets what its player sees and returns one action:

from codepraxis_football import Action

def agent(obs):
    me = obs['left_team'][obs['active']]
    if me[0] > 0.7:
        return Action.SHOT
    return Action.RIGHT

Agents that need memory can use a class instead:

class Agent:
    def reset(self):          # start of every episode
        self.steps = 0
    def act(self, obs):
        self.steps += 1
        return Action.RIGHT

Optional settings at the top of the file:

Setting Default Meaning
OBSERVATION 'raw' 'raw' (dict), 'vector' (115 numbers), 'minimap' (72x96x4), 'pixels' (72x96x3, slow)
PLAYERS 1 How many of our players you control. With more than 1, obs is a list and you return a list

The pitch

x runs from -1 (our goal) to 1 (the goal you attack). y runs from -0.42 (top) to 0.42 (bottom). You always attack to the right, also when the judges play your agent as the other team.

Raw observation fields

Field Meaning
ball [x, y, z] ball position (z = height)
ball_direction [x, y, z] ball movement per step
ball_owned_team -1 nobody, 0 us, 1 them
ball_owned_player index of the player with the ball
left_team, right_team [x, y] of every player (left = us)
left_team_direction, right_team_direction movement per step of every player
left_team_roles, right_team_roles 0 GK, 1 CB, 2 LB, 3 RB, 4 DM, 5 CM, 6 LM, 7 RM, 8 AM, 9 CF
left_team_tired_factor, right_team_tired_factor 0 fresh to 1 exhausted
left_team_yellow_card, left_team_active (and right) cards; active False = sent off
active index (in left_team) of the player you control
sticky_actions 10 flags: 8 directions, sprint, dribble (on until released)
score [ours, theirs]
steps_left steps until the episode ends
game_mode 0 normal, 1 kick-off, 2 goal kick, 3 free kick, 4 corner, 5 throw-in, 6 penalty

Actions

# Action # Action
0 IDLE 10 HIGH_PASS
1-8 LEFT, TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT 11 SHORT_PASS
9 LONG_PASS 12 SHOT
13 SPRINT 14 RELEASE_DIRECTION
15 RELEASE_SPRINT 16 SLIDING
17 DRIBBLE 18 RELEASE_DRIBBLE

Directions, sprint and dribble stay on until released. Passes and shots go the way the player faces.

Use it from Python (training)

import codepraxis_football as cpf

env = cpf.make('shoot_keeper', observation='vector')    # Gymnasium API
obs, info = env.reset(seed=0)
obs, reward, terminated, truncated, info = env.step(cpf.Action.SHOT)

reward is +1 for our goal and -1 for theirs. With no window the game runs at several hundred steps per second per CPU core; run one environment per core to train faster:

import gymnasium as gym

def make_env():
    return cpf.make('shoot_keeper', observation='vector')

if __name__ == '__main__':
    envs = gym.vector.AsyncVectorEnv([make_env] * 4)   # 4 processes
    obs, info = envs.reset(seed=[0, 1, 2, 3])

On a 2024 laptop, 4 environments run ~1,500 steps/s: a million training steps in about 11 minutes.

Reinforcement learning

Any library that speaks Gymnasium works. With Stable-Baselines3 (pip install stable-baselines3):

from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import SubprocVecEnv, VecMonitor
import codepraxis_football as cpf

def make_env():
    return cpf.make('shoot_keeper', observation='vector', reward='checkpoints')

if __name__ == '__main__':
    envs = VecMonitor(SubprocVecEnv([make_env] * 4))
    model = PPO('MlpPolicy', envs, n_steps=512, batch_size=512, gamma=0.993)
    model.learn(total_timesteps=2_000_000)
    model.save('model')

reward='checkpoints' adds small rewards for carrying the ball towards the goal, so learning starts long before the first goal. Use the saved model as an agent:

import os
from stable_baselines3 import PPO
OBSERVATION = 'vector'
model = PPO.load(os.path.join(os.path.dirname(__file__), 'model.zip'))  # next to agent.py

def agent(obs):
    return int(model.predict(obs, deterministic=True)[0])

Scoring

eval runs your agent for 100 episodes with fixed seeds and prints JSON: goal_rate (episodes where you scored), avg_steps_to_goal, wins/draws/losses, timeouts and errors. A step slower than 50 ms counts as IDLE. If your agent raises an error, that episode scores nothing and the rest still run. The judges use the same command with seeds you haven't seen.

Make your own practice level

See my_level.py from init. Use a level file anywhere a level name goes: codepraxis-football watch agent.py my_level.py.

Metadata

Release files for codepraxis-football 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for codepraxis-football 0.1.0
File Actions
codepraxis_football-0.1.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details for codepraxis_football-0.1.0-cp312-abi3-win_amd64.whl
codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64, Linux glibc 2.27+ ARM64 Details for codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
codepraxis_football-0.1.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details for codepraxis_football-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
codepraxis_football-0.1.0-cp312-abi3-macosx_10_15_x86_64.whl CPython 3.12 abi3 macOS 10.15+ x86-64 Details for codepraxis_football-0.1.0-cp312-abi3-macosx_10_15_x86_64.whl

Total release size: 10.7 MB

Release files / codepraxis_football-0.1.0-cp312-abi3-win_amd64.whl

Download URL codepraxis_football-0.1.0-cp312-abi3-win_amd64.whl
Size 1.9 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
9e5fcb3015d4694f9bdf02fa0e29d3a8a1ad3331bc04297a636e5498e72c5d28
BLAKE2b-256 checksum
How to use checksums
1124720e0430408dc732a6869d78a3586be9f1fda1957808ce2488265232c473
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Release files / codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 2.6 MB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
35a8ff8072ff6d70d4a0b3e4584c78890c43e28c3e84c489cd882cced2c3e7c9
BLAKE2b-256 checksum
How to use checksums
d2808867578661ffa85820b227aff9e8c933f3e6264f41cace492b21cd4a5686
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Release files / codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL codepraxis_football-0.1.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 2.4 MB
Tags CPython 3.12 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
6e0f9a05f27c0c476557d9e0bf224b5c5da5e44740e2a1ae410ebd140612733f
BLAKE2b-256 checksum
How to use checksums
4c0feb143db3e2cf7cdd2d4924241eff6ff1d64391e586e47ffac20bb25afdb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Release files / codepraxis_football-0.1.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL codepraxis_football-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
Size 1.8 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
10d590050226928a384ff9484b3d32cd749dc50a1da58bcea4cf271d3806023f
BLAKE2b-256 checksum
How to use checksums
921142e6ad4b078b8ce0d534adb1ad8205dae4f52152c0352cd7a80a66133982
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Release files / codepraxis_football-0.1.0-cp312-abi3-macosx_10_15_x86_64.whl

Download URL codepraxis_football-0.1.0-cp312-abi3-macosx_10_15_x86_64.whl
Size 2.0 MB
Tags CPython 3.12 abi3 macOS 10.15+ x86-64
SHA-256 checksum
How to use checksums
101785e7bf388c7f82f21bb581f2582fafccb1614b556e556bf2cb507eb3d848
BLAKE2b-256 checksum
How to use checksums
c703ced7b9abcb9342a4becc35e207320918058f37d1b61f6b9f308743c584e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Security for codepraxis-football 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page