Contributing
Thanks for your interest in contributing! This guide covers:
The Simple procedure for contributing to the project if you just want to add new agent types without modifying the code
The General procedure for contributing to the project
How to set up and test the Python wrapper and the mechanical layer
What happens in the continuous integration when you open a pull request
Simple procedure
A simple option if you want to add a different type of agents (e.g., pedestrian with a backpack, etc.) consists in generating your own XML files corresponding to these new agents (following the guidelines in the paper), reviewing them carefully, and sending them to the authors of the paper along with your motivations and explanations so that they could include them into a new release of the software.
General procedure
The master branch is protected: direct pushes are not allowed.
All changes must go through a pull request (PR). Here is how you should proceed:
On GitHub, fork the repository to create your own copy.
Clone your fork to your local machine, preferably on macOS or Ubuntu. On Windows, extra care is needed because the continuous integration does not run on Windows.
Create a new branch from
master:git checkout master git pull git checkout -b feature/short-description
Set up the required Python and C++ environments (detailed below).
Make your changes.
Run the hooks defined in the
.pre-commit-config.yamlfile:uv run pre-commit run --all-files
Run the mechanical layer tests:
cd tests/mechanical_layer ./run_mechanical_tests.sh cd ../..
Commit your changes.
Push your branch:
git push -u origin feature/short-description
Open a pull request on GitHub targeting
master. The configured checks (detailed below) will run automatically and their status will appear on the PR.
A PR is ready to merge when:
All automated checks are green (pre-commit.ci and GitHub Actions checks).
The code has been reviewed and approved by at least one collaborator.
The commit history is reasonably clean.
There are two main types of checks:
Style and quality checks, which enforce formatting, coding conventions, documentation rules, and basic static analysis.
Functional checks, which run tests to ensure the expected behavior is correct.
Working on the Python wrapper
To work on the Python wrapper:
Install Python (version 3.13).
Install and configure the uv package manager to set up the Python virtual environment with all required dependencies:
python -m pip install --upgrade pip pip install uv uv sync
This creates and manages a virtual environment for you and installs all dependencies (including development dependencies).
You can then modify the Python code as needed.
Before committing, run in the repository root:
uv run pre-commit run --all-files --skip clang-tidy,clang-format,cpplint
Here
--skipis used to avoid running the C++-related hooks locally when you are only modifying Python code, which saves time.
Working on the C++ mechanical layer
To work on the C++ part, you need a working C++ toolchain. On macOS this includes LLVM/Clang and CMake. The C++ mechanical layer has its own build and test workflow:
You first need to build the C++ project. From the repository root, run:
cd src/mechanical_layer cmake -H. -Bbuild -DBUILD_SHARED_LIBS=ON cmake --build build cd ../..
Modify the code as you want.
Run mechanical layer pre-commit hooks and tests. The tests depend on the Python wrapper, so you must set up the required Python virtual environment as explained above. Then, from the repository root:
uv run pre-commit run --all-files cd tests/mechanical_layer ./run_mechanical_tests.sh
Additionally, you may want to visualize the outputs of the mechanical layer tests:
./make_tests_videos.sh
The generated videos are stored in
/test/mechanical_layer/movies/.
Continuous Integration (CI)
For every pull request targeting master, two categories of automated checks run on both macos-latest and ubuntu-latest runners.
Pre-commit checks (via pre-commit.ci service)
The pre-commit.ci service runs most of the hooks defined in .pre-commit-config.yaml, including for example:
Spell checking (codespell)
Python formatting and linting (ruff, ruff-format)
Python type checking (mypy)
Python docstring validation (numpydoc-validation)
Notebook checks and upgrades (nbqa-ruff, nbqa-pyupgrade)
Shell formatting (shfmt)
C/C++ formatting and style checks (clang-format, cpplint)
Some more complex hooks that require the C++ library built or the Python environment are skipped here and are handled instead by GitHub Actions (see below).
GitHub Actions workflow: CI
On each pull request, GitHub Actions runs the workflow called CI (continuous integration). Here are the main steps:
Check out the repository.
Install LLVM and Graphviz (on macOS).
Install the latest Doxygen.
Set up Python, install
uv, and synchronize dependencies.Install the pre-commit hook.
Build the C++ mechanical layer with CMake.
Run selected pre-commit hooks and test scripts:
check-copyright(verify that the copyright headers are present and correctly formatted using the.check-copyright.shscript.)uv-pytest(Python configuration tests via the pytest package)test-notebooks(Jupyter notebook tests via the local shell script.check-notebooks.sh, only onmacos-latestrunner)check-doxygen(C++ documentation tests via the local shell script.check-doxygen.sh)
Run the mechanical layer tests.
All of these checks must succeed before the PR can be merged.
Reporting issues and proposing changes
If you are unsure about something, open an issue and describe:
The problem you are trying to solve.
The proposed solution.
Any open design questions (for example, API changes or performance implications).
Maintainers can then provide early feedback before you invest too much time in a particular direction.