dmlab-gym
A Gymnasium port of DeepMind Lab — 44 first-person 3D environments for Reinforcement Learning research, updated for Bazel 8 and Python 3.13.
What is this?
This project wraps the original DeepMind Lab C engine (Quake 3 based) as standard Gymnasium environments.
The C game code remains unchanged with deprecation warnings removed. This package only adds a Python interface layer around it.
Key features
- Standard
gym.make()API for all 44 levels - Compatible with all standard Gymnasium wrappers
- Vectorized environments via
gym.make_vec() - Python 3.13+ support
- Managed with
uvandpyproject.toml
Installation
pip install dmlab-gym
Requirements: Python 3.13+ (64-bit), Linux x86_64.
| Platform | Status |
|---|---|
| Linux (x86_64) | Supported |
| macOS | Not supported |
| Windows | Not supported |
Prerequisites
- uv (Python environment management)
- Podman or Docker (container builds)
- OSMesa (runtime dependency for headless rendering) — installed automatically by
dmlab-gym buildif missing
Manual OSMesa install
| Distribution | Command |
|---|---|
| Fedora / RHEL | sudo dnf install mesa-libOSMesa or mesa-compat-libOSMesa |
| Bluefin / immutable | sudo dnf install --transient mesa-compat-libOSMesa (resets on reboot) |
| Ubuntu / Debian | sudo apt install libosmesa6 |
| Arch | sudo pacman -S mesa |
Building the Native Extension
After installing, build the DeepMind Lab native extension:
dmlab-gym build # build and install deepmind-lab
dmlab-gym build -o ~/my_output # custom output directory
dmlab-gym build --no-install # build only, skip install
This auto-detects Podman or Docker, builds the native extension inside a container, installs the wheel, and verifies the import automatically.
Example output
$ dmlab-gym build
Building deepmind-lab (podman)
Source: /home/user/.local/share/dmlab-gym/source
Output: /home/user/my-project/lab
✓ Building container image
✓ Compiling native extension (this may take a while)
✓ Installing wheel
✓ deepmind_lab is importable
Done! deepmind-lab installed from deepmind_lab-1.0-py3-none-any.whl
Quick Start
Single environment (standard Gymnasium API)
import gymnasium as gym
import dmlab_gym # auto-registers all 44 levels
env = gym.make("dmlab_gym/lt_chasm-v0")
obs, info = env.reset()
for _ in range(1000):
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
obs, info = env.reset()
env.close()
Vectorized environments (parallel training)
DMLab's C engine only supports one instance per process. Use gym.make_vec to run N copies in separate subprocesses — each gets its own memory-isolated process and stays alive between steps:
import gymnasium as gym
import dmlab_gym
vec_env = gym.make_vec(
"dmlab_gym/lt_chasm-v0",
num_envs=8,
vectorization_mode="async",
)
obs, infos = vec_env.reset()
obs, rewards, terminated, truncated, infos = vec_env.step(vec_env.action_space.sample())
vec_env.close()
To customise environment options (resolution, renderer, etc.), use dmlab_gym.register() to re-register with different settings.
Environments
All environments produce (H, W, 3) RGB observations and use a 7D integer action space Box(shape=(7,), dtype=np.intc). See docs/environments/ for detailed per-group documentation.
| Group | Count | Levels | Description |
|---|---|---|---|
| Core | 12 | lt_chasm, lt_hallway_slope, lt_horseshoe_color, lt_space_bounce_hard, nav_maze_random_goal_01, nav_maze_random_goal_02, nav_maze_random_goal_03, nav_maze_static_01, nav_maze_static_02, nav_maze_static_03, seekavoid_arena_01, stairway_to_melon |
Laser tag arenas and maze navigation |
| Rooms | 7 | rooms_collect_good_objects_test, rooms_collect_good_objects_train, rooms_exploit_deferred_effects_test, rooms_exploit_deferred_effects_train, rooms_keys_doors_puzzle, rooms_select_nonmatching_object, rooms_watermaze |
Object interaction, memory, and planning |
| Language | 4 | language_answer_quantitative_question, language_execute_random_task, language_select_described_object, language_select_located_object |
Grounded language understanding |
| LaserTag | 4 | lasertag_one_opponent_large, lasertag_one_opponent_small, lasertag_three_opponents_large, lasertag_three_opponents_small |
Procedural laser tag with bots |
| NatLab | 3 | natlab_fixed_large_map, natlab_varying_map_randomized, natlab_varying_map_regrowth |
Mushroom foraging in naturalistic terrain |
| SkyMaze | 2 | skymaze_irreversible_path_hard, skymaze_irreversible_path_varied |
Irreversible platform navigation |
| PsychLab | 4 | psychlab_arbitrary_visuomotor_mapping, psychlab_continuous_recognition, psychlab_sequential_comparison, psychlab_visual_search |
Cognitive psychology experiments |
| Explore | 8 | explore_goal_locations_large, explore_goal_locations_small, explore_object_locations_large, explore_object_locations_small, explore_object_rewards_few, explore_object_rewards_many, explore_obstructed_goals_large, explore_obstructed_goals_small |
Maze exploration and object collection |
Access level lists via dmlab_gym.CORE_LEVELS, dmlab_gym.DMLAB30_LEVELS, or dmlab_gym.ALL_LEVELS.
Environment Options
All options can be passed as keyword arguments to dmlab_gym.register() or directly to DmLabEnv:
| Option | Default | Description |
|---|---|---|
renderer |
"software" |
"software" (headless OSMesa) or "hardware" (OpenGL) |
width |
84 |
Observation pixel width |
height |
84 |
Observation pixel height |
fps |
60 |
Frames per second |
max_num_steps |
0 |
Maximum steps per episode (0 = unlimited) |
observations |
["RGB_INTERLEAVED"] |
Observation channels to request from the engine |
Wrappers
One custom wrapper included:
| Wrapper | Description |
|---|---|
ActionDiscretize |
Converts the 7D action space to Discrete(9) using the IMPALA action set |
from dmlab_gym.wrappers import ActionDiscretize
env = ActionDiscretize(gym.make("dmlab_gym/lt_chasm-v0", renderer="software"))
env.action_space # Discrete(9)
Gymnasium Wrapper Compatibility
All standard Gymnasium wrappers are compatible:
| Wrapper | Compatible | Notes |
|---|---|---|
GrayscaleObservation |
Yes | RGB to grayscale conversion |
ResizeObservation |
Yes | Resize to any resolution (requires gymnasium[other]) |
FrameStackObservation |
Yes | Stack N consecutive frames |
MaxAndSkipObservation |
Yes | Frame skipping with max pooling |
ReshapeObservation |
Yes | Reshape observation arrays |
RescaleObservation |
Yes | Best used after DtypeObservation(float) |
DtypeObservation |
Yes | Convert uint8 to float32/float64 |
FlattenObservation |
Yes | Flatten to 1D |
NormalizeObservation |
Yes | Running mean/std normalisation |
TransformObservation |
Yes | Custom observation function |
TimeLimit |
Yes | Truncate after N steps |
ClipReward |
Yes | Bound rewards to a range |
NormalizeReward |
Yes | Normalise rewards via running stats |
TransformReward |
Yes | Custom reward function |
RecordEpisodeStatistics |
Yes | Track episode returns and lengths |
RecordVideo |
Yes | Requires render_mode="rgb_array" and moviepy |
HumanRendering |
Yes | Requires render_mode="rgb_array" and pygame |
FilterObservation |
No | Box observation space (not Dict) |
ClipAction |
Yes | Clips actions to Box bounds |
RescaleAction |
No | Float rescaling produces NaN with integer action space |
License
This project is a derivative work of DeepMind Lab and is distributed under the same licenses:
- GPLv2 --
engine/,q3map2/,assets_oa/ - CC BY 4.0 --
assets/ - Custom academic license --
engine/code/tools/lcc/ - BSD 3-Clause --
q3map2/libs/{ddslib,picomodel}
See LICENSE for full details.
Attribution
Based on DeepMind Lab by DeepMind.
Metadata
Release files for dmlab-gym 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| dmlab_gym-0.2.0.tar.gz | 53.4 kB | Without provenance | Details for dmlab_gym-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| dmlab_gym-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for dmlab_gym-0.2.0-py3-none-any.whl |
Total release size: 78.8 kB
Release files / dmlab_gym-0.2.0.tar.gz
| Download URL | dmlab_gym-0.2.0.tar.gz |
|---|---|
| Size | 53.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d8c3a7eeb0434df9f9b881b4f016052f229dec6596ce59a1d5da762140ccd207
|
|
BLAKE2b-256 checksum How to use checksums |
b60885c2aef47f305ecee0e730fe9dd22e186325e645d07552da45eac404124c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / dmlab_gym-0.2.0-py3-none-any.whl
| Download URL | dmlab_gym-0.2.0-py3-none-any.whl |
|---|---|
| Size | 25.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e24332b9c04b9734f6e803f1e6d0604b6ae1a65f75cf8abcbe2041eabf997b1
|
|
BLAKE2b-256 checksum How to use checksums |
1701d03a502b37e698d67f370382f50f98e1cd58898086f25dbdbc46141fcd9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for dmlab-gym 0.2.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.