ViZDoom: Doom as a Visual Reinforcement Learning Environment
Reinforcement Learning environments based on the 1993 game Doom :godmode:
At a glance
- What is it?
- ViZDoom wraps the ZDoom engine in a Python and C++ API that feeds screen buffers, depth buffers and game state to learning agents. It is a research platform with a real maintenance surface, and the 1.3.0 release narrows which platforms get prebuilt wheels.
- Who is it for?
- Adopt ViZDoom if you need a pixel-input RL environment with scriptable scenarios, depth and label buffers, and a Gymnasium wrapper that ships in the same pip package. Do not adopt it if you need original Doom assets out of the box, if you are on Intel macOS and want a current wheel, or if Windows is your only serious training host.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap ViZDoom fills: pixels in, actions out, no game code required
Most reinforcement learning benchmarks hand the agent a compact state vector. ViZDoom does the opposite. The README states that it allows developing bots that play Doom using only visual information, specifically the screen buffer, and that it is primarily intended for research in machine visual learning and deep reinforcement learning. That framing matters because it sets the difficulty: the agent has to recover geometry, enemies and projectile trajectories from rendered frames rather than from a hand-built feature vector.
The intended audience is narrow and identifiable. It is researchers who need a first-person 3D task where the observation is an image, where episodes have a clear terminal condition, and where the environment is cheap enough to run thousands of steps per second on one machine. The README puts the ceiling at up to 7000 frames or steps per second in sync mode, single-threaded, on a modern CPU. That number is a documentation claim, not something this article measured, but it is the kind of figure that decides whether a pixel-based experiment finishes overnight or over a week.
The project also positions itself beyond plain RL. The README says the API is suitable for learning from demonstration, apprenticeship learning and apprenticeship via inverse reinforcement learning. Those use cases need recorded trajectories, and the feature list includes episode recording, which is the mechanism that makes them possible.
What sits between the agent and the ZDoom engine
ViZDoom is not a reimplementation of Doom. The README states it is based on the ZDoom engine to provide the game mechanics. The learning-facing layer is a separate API bound to that engine, exposed for Python and C++, with the two bindings kept deliberately close: the README notes the API is almost identical between the languages, differing only in snake_case for Python and camelCase for C++.
The observation surface is broader than the screen buffer alone. According to the feature list, the environment can expose the depth buffer for 3D vision, an audio buffer, the list of actors and objects plus map geometry, in-game text messages and notifications, and automatic labeling and categorization of game objects visible in the frame. The 1.3.0.dev3 release notes add label categories intended for semantic segmentation, and mention a new notifications buffer alongside audio buffer improvements. For an agent that only needs pixels, none of this is required. For a research setup that wants to compare a vision-only agent against one with privileged state, these channels are the comparison.
Rendering is configurable. The feature list includes customizable resolution and rendering parameters and off-screen rendering, which is what lets a headless training run avoid opening a window. Scenarios are not hardcoded: the README describes easy-to-create custom scenarios with visual editors, a scripting language and examples. Execution comes in sync and async variants, single-player and multiplayer, and the async mode supports in-game time scaling. The sync mode is the one the frame-rate figure refers to.
Installing ViZDoom 1.3.0, and where the wheels stop
The common path is a single pip command on all three platforms:
pip install vizdoom
What that resolves to depends on your machine, and the README is explicit about the boundaries. On Linux, wheels cover Python 3.10+ and both x86-64 and AArch64. Audio features need OpenAL present on the system, installed with apt install libopenal-dev on apt-based distributions or dnf install openal-soft-devel on dnf and yum based ones. If no wheel matches, pip falls back to building from source, which requires a C++11 compiler, CMake 3.12+, Boost 1.54+, SDL2 and optionally OpenAL.
macOS changed in this release and the change is worth reading twice. Since 1.3.0, prebuilt wheels exist only for Apple Silicon on macOS 14.0 or later. Intel Macs on macOS 13.0+ are told to pin the older release with pip install vizdoom==1.2.4. That is a hard fork in the user base: a current version on one architecture, a frozen 1.2.4 on the other, unless you build from source.
Windows has wheels for Python 3.10+ on x86-64 only. The README also carries a warning that the Windows version is not as well tested as Linux and macOS, and suggests Docker or WSL with the Linux version for time and resource intensive experiments. That is unusually direct self-assessment from a project README, and it should be taken at face value when planning a long training run.
Gymnasium environments install alongside ViZDoom and are available on all platforms, with documentation and an example script referenced from the README.
The asset boundary: Freedoom by default, doom2.wad if you own it
This is the constraint that surprises people first. The README states plainly that ViZDoom cannot be distributed with original Doom graphics. The default content is Freedoom, a free replacement. If you own the original Doom and Doom 2, you can substitute the retail assets by placing doom2.wad into your working directory or into the vizdoom package directory.
The consequence is that a fresh install does not give you the maps most published Doom RL results were produced on. The 1.3.0 release notes mention original Doom levels, which suggests the tooling around level selection has moved, but the distribution restriction itself is a licensing matter rather than a technical one, and the README does not indicate it has changed. The repository metadata supplied here lists the license as unknown, so the licence terms of ViZDoom itself cannot be confirmed from this material. Anyone planning to redistribute a modified build, or to ship a scenario with bundled assets, needs to resolve both questions separately: the licence of the code, and the provenance of every WAD in the package.
Where ViZDoom is the wrong tool
The first failure mode is platform drift. If your lab standardises on Intel Macs, you are on 1.2.4 while the project moves forward, and the gap will widen with each release. Building from source is the escape hatch, but it pulls in Boost, SDL2 and CMake version floors that a pip-only workflow does not otherwise need.
The second is the Windows testing gap. The README's own advice to prefer Docker or WSL for serious experiments means that a Windows-native training run is a development convenience, not a production configuration. Teams that cannot use WSL or Docker on their training hardware should treat this as disqualifying rather than as a caveat.
The third is the scenario model itself. ViZDoom is built around hand-authored scenarios with scripted reward logic, not around procedurally generated tasks. If your research question needs thousands of distinct levels generated on the fly, or needs a physics simulator you can instrument at the contact level, this is the wrong layer. The environment gives you a rendered game and a scripting language; it does not give you a differentiable or fully introspectable world model.
Finally, the frame-rate claim is stated for sync mode, single-threaded, on a modern CPU. Async mode exists and supports time scaling, but the README does not attach a throughput figure to it, so anyone whose pipeline depends on async execution should measure their own scenario rather than assume the sync number carries over.
Compared with a from-scratch simulator
The obvious alternative for pixel-based control research is to build the task in a general robotics or game simulator and render observations yourself. The difference in approach is where the world comes from. With a general simulator you author the environment, its physics and its reward function, and you own the rendering pipeline and its cost. With ViZDoom you inherit a shipped game: the ZDoom engine supplies movement, collision, hitscan and projectile behaviour, and the scenario editor and scripting language supply the task definition on top.
That inheritance is the whole value proposition. You get a first-person 3D world with mature, fixed mechanics and no simulation-fidelity argument to defend, because the dynamics are a released game rather than an approximation. You also get the auxiliary channels, depth, labels, actor lists and map geometry, without writing renderer instrumentation.
The cost is control. You cannot change how the engine resolves a collision, you cannot make the world differentiable, and your task design is bounded by what the scripting layer exposes. A team whose research question is about the simulator itself, rather than about an agent learning from pixels, will find ViZDoom's fixed engine a wall rather than a foundation.
Maintenance cost and what to check before you commit
The release cadence visible here is steady rather than fast: 1.3.0.dev3 in October 2025, 1.3.0rc1 in early February 2026, 1.3.0 on 11 February 2026, and a push to main in September 2026. The 1.3.0 release is labelled a mature Farama release, and the dev3 notes describe maintenance alongside the audio and notification buffers and the new label categories. That pattern suggests incremental work on the observation surface rather than churn in the core API.
The upgrade cost is concentrated at the platform boundary, not in the Python API. The 1.3.0 notes flag original Doom levels and Python 3.14 support in the release candidate, and the macOS wheel policy changed in this version. A team on Intel macOS upgrading past 1.2.4 has to either build from source or stay pinned, and a team relying on the audio buffer has to confirm OpenAL is present on every machine in the training fleet. The C++ and Python bindings track each other closely, so a mixed-language codebase does not carry a separate upgrade burden beyond the snake_case and camelCase naming difference.
On licensing, the supplied metadata records the licence as unknown, so no statement about ViZDoom's own terms can be made here. What can be said is that the bundled assets are Freedoom and that original Doom graphics are not distributed. Any deployment that ships ViZDoom, or that places a retail doom2.wad into the package directory, raises a separate question about the WAD's terms that the project documentation does not answer. That is a question for whoever handles licensing in your organisation, not something this article can settle.
Editorial conclusion
Adopt ViZDoom if you need a pixel-input RL environment with scriptable scenarios, depth and label buffers, and a Gymnasium wrapper that ships in the same pip package. Do not adopt it if you need original Doom assets out of the box, if you are on Intel macOS and want a current wheel, or if Windows is your only serious training host. Verify three things before committing: that a wheel exists for your Python version and platform, that libopenal is installed if you plan to touch the audio buffer, and that your scenario's reward logic is expressible in the ACS scripting the scenario editor exposes.
Community notes