scenario_runner: traffic scenarios and OpenSCENARIO for CARLA
Traffic scenario definition and execution engine
At a glance
- What is it?
- The CARLA Scenario Runner is the piece of tooling between a scenario file and the simulator: it defines traffic situations in Python or in the OpenSCENARIO format and executes them against a running CARLA server. Its real constraint is version coupling, since each release is matched to a specific CARLA release.
- Who is it for?
- Adopt scenario_runner if you are working with CARLA and want repeatable traffic situations rather than ad-hoc scripts, especially if your scenarios come from the OpenSCENARIO standard or you intend to enter the CARLA Autonomous Driving Leaderboard evaluation.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The layer between a scenario file and a running simulator
The CARLA Scenario Runner is described in one line as a traffic scenario definition and an execution engine for CARLA. That framing is the key to understanding it, because it is neither the simulator nor a driving agent. It is the harness that turns a described situation into traffic in the world.
A scenario describes who does what and when. The runner takes that description and executes it: spawning actors, applying behaviour, driving the episode, and tearing it down again. The project also states that it allows the execution of a simulation of the CARLA Challenge, so that an agent can be prepared for a competition before the competition itself, and its own repository topics are carla, openscenario and traffic-scenario.
The primary language is Python, the licence for the scenario runner specific code is MIT, and the documentation is published at scenario-runner.readthedocs.io. The code lives in a `srunner/` package with entry points such as `scenario_runner.py`, alongside `manual_control.py`, `metrics_manager.py` and `no_rendering_mode.py`, a `tests/` directory and a `Docs/` tree that feeds the readthedocs build through `mkdocs.yml`.
The audience is a simulation engineer or a research team that already runs CARLA. This is not a tool for learning what a driving simulator does, and it is not a data collection platform in its own right.
Two ways to write a scenario: Python and OpenSCENARIO
The project supports two authoring routes, and that duality is its most useful property for a research group.
The first is a Python interface, where a scenario is expressed in code. This is the flexible path. You can compute trajectories, seed randomness and branch on conditions, because the definition is a program rather than a document.
The second is the file-based route. The documentation states that with the newest version the runner also supports the OpenSCENARIO standard and the OpenSCENARIO 2.0 standard from ASAM. This is the portable path, because a scenario written in the standard format is not tied to this runner's Python API and can be exchanged with other tools that speak the same format.
The dependency list gives a hint about how the standard is parsed. `xmlschema==1.0.18` validates XML documents against a schema, and `antlr4-python3-runtime==4.10` is the runtime for the ANTLR parser generator, which is the usual way to handle the grammar-driven parts of a structured document format. `py-trees==0.8.3` is the behaviour tree library, and behaviour trees are the mechanism by which a scenario's steps are sequenced and made conditional.
The geometric side of the work is handled by `Shapely==2.1.1` and `networkx==3.4.2`, which is what you would expect for lane geometry and route topology. If your scenario depends on precise positions, those two libraries are where the correctness of your map logic lives.
Version matching is the entire installation problem
The installation instructions are short because the hard part is not building, it is choosing a release that matches your simulator. The documentation states plainly that no build is required, since all the code is in Python, and the master branch contains the latest fixes and features and may be required to use the latest features from CARLA.
Then comes the warning that decides everything else: it is important to consider the release version that has to match the CARLA version. The README lists the pairings explicitly. Version 0.9.16 and the 0.9.16 branch are compatible with CARLA 0.9.16, version 0.9.15 pairs with CARLA 0.9.15, and version 0.9.13 works with CARLA 0.9.13 and CARLA 0.9.14. The list continues down to 0.9.2, with 0.9.12, 0.9.11, 0.9.10, 0.9.9, 0.9.8, 0.9.7, 0.9.6, 0.9.5 and 0.9.2 each tied to their own simulator release.
Two entries in that table deserve attention. The 0.9.9 entry says to use the 0.9.9 branch if you use CARLA 0.9.9.4, and the 0.9.7 entry says it is compatible with CARLA 0.9.7 but not with the later patch versions. Patch-level differences matter here, which is unusual and worth internalising before you plan a CI matrix.
To pick a specific version you can download the corresponding tarball or check out the version tag associated with the release, and the master branch is where new work lands.
Pinned dependencies, and why the requirements file is short and strict
There is no build step, but there is a dependency contract, and it is pinned tightly. The requirements file names exact versions for the parts that affect behaviour:
py-trees==0.8.3
numpy==1.24.4; python_version >= '3.0'
networkx==3.4.2
Shapely==2.1.1
xmlschema==1.0.18
antlr4-python3-runtime==4.10
opencv-python==4.7.0.72The remaining entries are unpinned: `psutil`, `ephem`, `tabulate`, `matplotlib`, `six`, `simple-watchdog-timer` and `graphviz`. `ephem` is the astronomy library, which is an odd looking dependency until you remember that CARLA scenarios routinely involve sun position, and `simple-watchdog-timer` suggests scenarios can wait on time conditions rather than only frame counts.
The mismatch risk is real. The `Dockerfile` in the repository is built `from ubuntu:18.04` and installs `python3.6` and `python3.6-dev`, and it pins a different, older set of libraries for the same project, including `py_trees==0.8.3 networkx==2.2 pygame==1.9.6` and `numpy==1.18.4`. The container image and the current requirements file are not the same dependency set, so a scenario that works in the image may behave differently when you install from `requirements.txt` on a newer Python, and the reverse is equally possible.
For an image build the `Dockerfile` also expects the CARLA package to be fetched from a host and release pair, and the defaults are read from the `CARLA_VER` file at the repository root if the environment does not supply them.
A container build keyed on CARLA_HOST and CARLA_RELEASE
The `Dockerfile` shows how the simulator itself enters the picture. Two environment variables control it, and the file's own comments describe them: `CARLA_HOST` is the URI for the carla package without a trailing slash, and `CARLA_RELEASE` is the name of the package to be used, for example `CARLA_0.9.9`. The comments also state that if the environment is not passed to the docker build, the value is taken from the `CARLA_VER` file inside the repository, and that it is expected that `$(CARLA_HOST)/$(CARLA_RELEASE).tar.gz` is a downloadable resource.
The image therefore starts empty on those two variables and fills them in from the repository:
from ubuntu:18.04
env CARLA_HOST ""
env CARLA_RELEASE ""The scenario runner code itself is copied into the image with a single instruction, and the extraction step unpacks the Python API and resources from the downloaded CARLA archive:
copy . /app/scenario_runnerThe build also installs system libraries that CARLA's own dependencies require, among them `libpng16-16`, `libtiff5`, `libjpeg8` and `libxerces-c-dev`, plus `build-essential` and `git`.
There is a continuous integration story here too. The repository root holds a `Jenkinsfile` and the build badge points at Travis CI, and a `.pylintrc` shows that linting is configured. In other words, the project has the plumbing of a maintained component even though the release cadence is slow.
The Challenge has moved, so the runner is not the evaluation harness
One piece of the documentation reads like a historical note and saves you a wasted afternoon. The README explains that the CARLA Challenge has moved to the CARLA Autonomous Driving Leaderboard, and points to the leaderboard repository and its getting started guide for the current arrangement.
That is worth taking seriously. The runner still lets you execute a simulation of the CARLA Challenge, so the preparation workflow lives here, but the evaluation itself now lives elsewhere. A team preparing a leaderboard entry should not expect this repository to score the run.
The files hint at what the runner does track. `metrics_manager.py` sits next to `scenario_runner.py` in the root, and `no_rendering_mode.py` suggests a headless execution path, which matters because a scenario that spawns traffic and applies behaviour is far cheaper to run many times without a display attached. `manual_control.py` is the manual driving path, useful for authoring and sanity checking a scenario by hand before automating it.
The honest summary is that scenario_runner is a well-defined execution environment for traffic situations, and the competition scoring has been deliberately handed off to a separate repository.
Where the runner is the wrong tool
The clearest case for not adopting it is a single ad-hoc script. If you already drive CARLA from the Python API and you need one cut-in or one traffic jam, writing a small script directly against the simulator is less work than learning the runner's scenario model, its behaviour tree machinery and its version matrix. The runner pays for itself when you have a catalogue of scenarios, need them reproducible across runs, or need to hand them to someone else.
The second case is a version mismatch. Because each runner release is pinned to a CARLA release, and because the master branch may be required for the newest CARLA features, teams that upgrade the simulator frequently will spend real time on compatibility. The tags are there for stability, but they also mean the runner is at most as fresh as the simulator you run.
The third is container reproducibility. The `Dockerfile` targets ubuntu:18.04 with Python 3.6, which is a frozen base. It works, but it is not a base image you would choose today, and the older pinned dependencies inside it are not the same set as the current `requirements.txt`.
On maintenance, the repository is not archived and the last push was on 2026-10-19, so work is landing on master. The tagged releases are much older: v0.9.16 from 2025-09-29, v0.9.15 from 2023-11-16 and v0.9.13 from 2021-12-20. The gap between a live master branch and a three year old tag is the honest picture of this project, and it is the reason to check the compatibility table before pinning anything.
Editorial conclusion
Adopt scenario_runner if you are working with CARLA and want repeatable traffic situations rather than ad-hoc scripts, especially if your scenarios come from the OpenSCENARIO standard or you intend to enter the CARLA Autonomous Driving Leaderboard evaluation. Do not adopt it if your simulator work is a single bespoke Python script, since the version matching burden buys you a scenario layer you may not need, and do not treat it as the evaluation harness itself, since the Challenge moved to the leaderboard repository. First check that the CARLA release you run is listed as compatible with the runner tag you install, install the pinned dependencies from `requirements.txt`, and read the getting started documentation before writing your first scenario.
Frequently asked questions
Which scenario_runner version should I use with my CARLA release?
Each runner release is matched to a specific CARLA release. Version 0.9.16 pairs with CARLA 0.9.16, 0.9.15 pairs with CARLA 0.9.15, and 0.9.13 works with CARLA 0.9.13 and 0.9.14. The README lists the full table, and the master branch carries the latest fixes and may be needed for the newest CARLA features.
Does scenario_runner need to be compiled?
No. The documentation states that currently no build is required, as all code is in Python. You either clone the repository or download the tarball for the release you want, and you install the dependencies listed in `requirements.txt`.
Can scenario_runner read OpenSCENARIO files?
Yes. The project states that with the newest version the runner supports the OpenSCENARIO standard and the OpenSCENARIO 2.0 standard from ASAM. Scenarios can also be defined through a Python interface, so both a file-based and a programmatic route are available.
How do I evaluate a driving agent with scenario_runner?
The runner can execute a simulation of the CARLA Challenge, which is how you prepare an agent. The evaluation itself has moved to the CARLA Autonomous Driving Leaderboard, with the leaderboard repository and its getting started guide holding the current details.
How is the CARLA simulator package installed in the scenario_runner Dockerfile?
Two build arguments control it: `CARLA_HOST` is the URI for the carla package without a trailing slash, and `CARLA_RELEASE` names the package, for example `CARLA_0.9.9`. If they are not passed to the build, the values are read from the `CARLA_VER` file in the repository, and the archive is expected at `$(CARLA_HOST)/$(CARLA_RELEASE).tar.gz`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/carla-simulator-scenario-runner)Was this useful?