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 | |
|---|---|---|---|
| dmlab_gym-0.2.0.tar.gz | 53.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dmlab_gym-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
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}
|