Skip to main content

A Gymnasium chess environment for quality-latency research with language agents

Project description

gym-bullet-chess

gym-bullet-chess is a Gymnasium environment for studying whether an agent can trade move quality against the time consumed by its own reasoning.

The package does not contain a chess engine. python-chess is used only for rules, legal moves, and outcomes. A language agent may reason, call tools, or inspect a VLM-ready board image, but all work performed before it submits a move can consume its clock.

Install

python -m pip install -e ".[dev]"

Python 3.10 or newer is required.

Real-time evaluation

RealTimeClock measures from the instant an observation is returned until the next action reaches step(). Model inference, network latency, and tool calls inside that interval are charged to the side to move. Environment execution is excluded from the next decision's budget.

import gymnasium as gym
import gym_bullet_chess
from gym_bullet_chess import RealTimeClock

env = gym.make(
    "BulletChess-v0",
    initial_seconds=60.0,
    increment_seconds=0.0,
    include_board_image=True,
)
env = RealTimeClock(env)

observation, info = env.reset(seed=7)
action = int(observation["action_mask"].nonzero()[0][0])
observation, reward, terminated, truncated, info = env.step(action)

Reproducible latency experiments

Wall time is appropriate for evaluation but unsuitable for deterministic training. SimulatedClock injects a constant or scheduled latency while preserving the exact Discrete action contract.

from gym_bullet_chess import BulletChessEnv, SimulatedClock

env = SimulatedClock(
    BulletChessEnv(initial_seconds=10.0, increment_seconds=0.1),
    think_time=lambda decision_index, action: 0.05 + decision_index * 0.01,
)

The unwrapped environment also exposes step_timed(action, elapsed_seconds) for explicit experiment orchestration. Invalid, negative, NaN, and infinite durations are rejected.

Language and vision agents

Set include_board_image=True to include a headless RGB array:

Key Shape Type Meaning
board (8, 8, 18) float32 12 piece planes, turn, castling rights, and en-passant target
state (10,) float32 Rule state including repetition and claimable-draw features
clocks (2,) float32 Raw white and black seconds
action_mask (20481,) int8 Legal move and draw-claim actions
board_image (image_size, image_size, 3) uint8 Optional Cburnett RGB board image

info contains the FEN, legal UCI moves, both clocks, current view, last move, outcome, and timing fields. For language-model tools, use UCIActionWrapper and format_position_for_llm:

from gym_bullet_chess import (
    BulletChessEnv,
    RealTimeClock,
    UCIActionWrapper,
    format_position_for_llm,
)

env = RealTimeClock(UCIActionWrapper(BulletChessEnv(include_board_image=True)))
observation, info = env.reset()
prompt_context = format_position_for_llm(info)
observation, reward, terminated, truncated, info = env.step("e2e4")

The string claim_draw is accepted when a draw is legally claimable.

Actions and perspectives

The discrete action space covers all standard legal moves:

((from_square * 64) + to_square) * 5 + promotion_slot

Promotion slots are none, queen, rook, bishop, and knight. Action 20480 is a draw claim. This supports underpromotions instead of silently forcing a queen.

With perspective="side_to_move" (the default), board coordinates, images, action encoding, and action masks all rotate together for Black. Fixed white, black, and agent perspectives are also available. The helpers action_for_uci() and uci_for_action() avoid manual encoding.

Play modes

  • opponent=None: self-play. Each step advances one ply and terminal reward is relative to the side that submitted the action.
  • opponent="random": a seeded legal-move baseline responds automatically. Reward is always relative to agent_color.
  • Custom opponents implement select_move(board, rng) and return OpponentDecision(move, elapsed_seconds). Their latency is charged to their own clock.

The random opponent is a baseline for integration tests, not a substitute for an LLM agent or an evaluation opponent.

Rewards and endings

A win returns +1.0, a loss returns -1.0, and a draw returns 0.0. In self-play the result is relative to the actor that submitted the terminal action; against an opponent it is relative to agent_color. Illegal actions terminate the episode with illegal_move_reward (default -1.0). Clock expiration is a draw when the non-flagging side lacks mating material.

Experiment trace

env.unwrapped.episode_trace stores one record per decision with actor, source, integer action, UCI/SAN move, elapsed time, remaining time, and event. Terminal info["outcome"] records winner, result, and termination cause.

License and assets

The project is GPL-3.0-or-later because python-chess is GPL-3.0-or-later. Cburnett piece images are freshly downloaded Wikimedia rasterizations. The upstream multi-license, selected BSD-3-Clause terms, source URL for every file, and SHA-256 hashes are recorded in src/gym_bullet_chess/assets/ATTRIBUTION.md. Other dependency licenses are listed in THIRD_PARTY_LICENSES.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gym_bullet_chess-0.1.0.tar.gz (88.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gym_bullet_chess-0.1.0-py3-none-any.whl (89.8 kB view details)

Uploaded Python 3

File details

Details for the file gym_bullet_chess-0.1.0.tar.gz.

File metadata

  • Download URL: gym_bullet_chess-0.1.0.tar.gz
  • Upload date:
  • Size: 88.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for gym_bullet_chess-0.1.0.tar.gz
Algorithm Hash digest
SHA256 392222f1ae81426752ab7037a74c66afe0fd8158cad3835cc7b057f78d79e2cc
MD5 8fcb722d14fd4cb01a082726720d0fbd
BLAKE2b-256 4f81cdb652b9ede41d7bb99c7ebf717c66425451718f4ee08e7d291dcf344640

See more details on using hashes here.

Provenance

The following attestation bundles were made for gym_bullet_chess-0.1.0.tar.gz:

Publisher: release.yml on ChoiCube84/gym-bullet-chess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gym_bullet_chess-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for gym_bullet_chess-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a39433c42a98be783d2b39599da49c92c7dd5bad6e0d0d92fa40e6be8c898bd
MD5 62ff55c3f863899624c2df33e7c57947
BLAKE2b-256 82b2a2b38987b892158bc8d714c9c787c2ad70f3b50a9d0a118c0e63fc29c99f

See more details on using hashes here.

Provenance

The following attestation bundles were made for gym_bullet_chess-0.1.0-py3-none-any.whl:

Publisher: release.yml on ChoiCube84/gym-bullet-chess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page