# Laser Learning Environment (LLE)
LLE is a fast Multi-Agent Reinforcement Learning environment written in Rust which has proven to be a difficult exploration benchmark so far. The agents start in the start tiles, must collect the gems and finish the game by reaching the exit tiles. There are five actions: North, South, East, West and Stay.
When an agent enters a laser of its own colour, it blocks it. Otherwise, it dies and the game ends.
![LLE](docs/lvl6-annotated.png)
# Quick start
## Installation
You can install the Laser Learning Environment with pip or poetry.
```bash
pip install laser-learning-environment # Stable release with pip
pip install git+https://github.com/yamoling/lle # latest push on master
```
## Usage
LLE can be used at two levels of abstraction: as an `RLEnv` for cooperative multi-agent reinforcement learning or as a `World` for many other purposes.
### For cooperative multi-agent reinforcement learning
The `LLE` class inherits from the `RLEnv` class in the [rlenv](https://github.com/yamoling/rlenv) framework. Here is an example with the following map: ![LLE](docs/3x1.png)
```python
from lle import LLE
env = LLE.from_str("S0 G X").single_objective()
done = truncated = False
obs = env.reset()
while not (done or truncated):
# env.render() # Uncomment to render
actions = env.action_space.sample(env.available_actions())
obs, reward, done, truncated, info = env.step(actions)
```
### For other purposes or fine grained control
The `World` class provides fine grained control on the environment by exposing the state of the world and the events that happen when the agents move.
```python
from lle import World, Action, EventType
world = World("S0 G X") # Linear world with start S0, gem G and exit X
world.reset()
available_actions = world.available_actions()[0] # [Action.STAY, Action.EAST]
events = world.step([Action.EAST])
assert events[0].event_type == EventType.GEM_COLLECTED
events = world.step([Action.EAST])
assert events[0].event_type == EventType.AGENT_EXIT
```
You can also access and force the state of the world
```python
state = world.get_state()
...
events = world.set_state(state)
```
You can query the world on the tiles with `world.start_pos`, `world.exit_pos`, `world.gem_pos`, ...
## Citing our work
The environment has been presented at [EWRL 2023](https://openreview.net/pdf?id=IPfdjr4rIs) and at [BNAIC 2023](https://bnaic2023.tudelft.nl/static/media/BNAICBENELEARN_2023_paper_124.c9f5d29e757e5ee27c44.pdf) where it received the best paper award.
```
@inproceedings{molinghen2023lle,
title={Laser Learning Environment: A new environment for coordination-critical multi-agent tasks},
author={Molinghen, Yannick and Avalos, Raphaël and Van Achter, Mark and Nowé, Ann and Lenaerts, Tom},
year={2023},
series={BeNeLux Artificial Intelligence Conference},
booktitle={BNAIC 2023}
}
```
## Development
If you want to modify the environment, you can clone the repo, install the python dependencies then compile it with `maturin`. The below example assumes that you are using `uv` as package manager but it should work with `conda`, `poetry` or just `pip` as well.
```
git clone https://github.com/yamoling/lle
uv venv # create a virtual environment
source .venv/bin/activate
uv sync # install python dependencies
maturin dev # build and install lle in the venv
```
You can also re-generate the python bindings in the folder `python/lle` with
```bash
cargo run --bin stub-gen
```
## Tests
This project **does not** respect Rust unit tests convention and takes inspiration from [this structure](http://xion.io/post/code/rust-unit-test-placement.html). Unit tests are in the `src/unit_tests` folder and are explicitely linked to in each file with the `#path` directive.
Integration tests are written on the python side.
Run unit tests with
```bash
cargo test
```
Run integration tests with
```bash
maturin develop
pytest
```
Raw data
{
"_id": null,
"home_page": "https://github.com/yamoling/lle",
"name": "laser-learning-environment",
"maintainer": null,
"docs_url": null,
"requires_python": "<4,>=3.11",
"maintainer_email": null,
"keywords": "marl, rl, lle, laser, environment",
"author": null,
"author_email": "Yannick Molinghen <yannick.molinghen@ulb.be>",
"download_url": "https://files.pythonhosted.org/packages/e0/94/92e73a737aa11858efa3d031f1a740bcfc82046d728018b70401c8b39288/laser_learning_environment-2.0.0.tar.gz",
"platform": null,
"description": "# Laser Learning Environment (LLE)\nLLE is a fast Multi-Agent Reinforcement Learning environment written in Rust which has proven to be a difficult exploration benchmark so far. The agents start in the start tiles, must collect the gems and finish the game by reaching the exit tiles. There are five actions: North, South, East, West and Stay. \n\nWhen an agent enters a laser of its own colour, it blocks it. Otherwise, it dies and the game ends.\n\n![LLE](docs/lvl6-annotated.png)\n\n# Quick start\n## Installation\nYou can install the Laser Learning Environment with pip or poetry.\n```bash\npip install laser-learning-environment # Stable release with pip\npip install git+https://github.com/yamoling/lle # latest push on master\n```\n\n## Usage\nLLE can be used at two levels of abstraction: as an `RLEnv` for cooperative multi-agent reinforcement learning or as a `World` for many other purposes.\n### For cooperative multi-agent reinforcement learning\nThe `LLE` class inherits from the `RLEnv` class in the [rlenv](https://github.com/yamoling/rlenv) framework. Here is an example with the following map: ![LLE](docs/3x1.png)\n\n\n```python\nfrom lle import LLE\n\nenv = LLE.from_str(\"S0 G X\").single_objective()\ndone = truncated = False\nobs = env.reset()\nwhile not (done or truncated):\n # env.render() # Uncomment to render\n actions = env.action_space.sample(env.available_actions())\n obs, reward, done, truncated, info = env.step(actions)\n```\n\n\n### For other purposes or fine grained control\nThe `World` class provides fine grained control on the environment by exposing the state of the world and the events that happen when the agents move.\n\n```python\nfrom lle import World, Action, EventType\n\nworld = World(\"S0 G X\") # Linear world with start S0, gem G and exit X\nworld.reset()\navailable_actions = world.available_actions()[0] # [Action.STAY, Action.EAST]\nevents = world.step([Action.EAST])\nassert events[0].event_type == EventType.GEM_COLLECTED\nevents = world.step([Action.EAST])\nassert events[0].event_type == EventType.AGENT_EXIT\n```\n\nYou can also access and force the state of the world\n```python\nstate = world.get_state()\n...\nevents = world.set_state(state)\n```\n\nYou can query the world on the tiles with `world.start_pos`, `world.exit_pos`, `world.gem_pos`, ...\n\n\n\n\n## Citing our work\nThe environment has been presented at [EWRL 2023](https://openreview.net/pdf?id=IPfdjr4rIs) and at [BNAIC 2023](https://bnaic2023.tudelft.nl/static/media/BNAICBENELEARN_2023_paper_124.c9f5d29e757e5ee27c44.pdf) where it received the best paper award.\n\n```\n@inproceedings{molinghen2023lle,\n title={Laser Learning Environment: A new environment for coordination-critical multi-agent tasks},\n author={Molinghen, Yannick and Avalos, Rapha\u00ebl and Van Achter, Mark and Now\u00e9, Ann and Lenaerts, Tom},\n year={2023},\n series={BeNeLux Artificial Intelligence Conference},\n booktitle={BNAIC 2023}\n}\n```\n\n## Development\nIf you want to modify the environment, you can clone the repo, install the python dependencies then compile it with `maturin`. The below example assumes that you are using `uv` as package manager but it should work with `conda`, `poetry` or just `pip` as well.\n```\ngit clone https://github.com/yamoling/lle\nuv venv # create a virtual environment\nsource .venv/bin/activate\nuv sync # install python dependencies\nmaturin dev # build and install lle in the venv\n```\n\nYou can also re-generate the python bindings in the folder `python/lle` with\n```bash\ncargo run --bin stub-gen\n```\n\n\n## Tests\nThis project **does not** respect Rust unit tests convention and takes inspiration from [this structure](http://xion.io/post/code/rust-unit-test-placement.html). Unit tests are in the `src/unit_tests` folder and are explicitely linked to in each file with the `#path` directive. \nIntegration tests are written on the python side.\n\nRun unit tests with \n```bash\ncargo test\n```\n\nRun integration tests with\n```bash\nmaturin develop\npytest\n```\n\n",
"bugtrack_url": null,
"license": null,
"summary": "Laser Learning Environment (LLE) for Multi-Agent Reinforcement Learning",
"version": "2.0.0",
"project_urls": {
"Homepage": "https://github.com/yamoling/lle",
"Source Code": "https://github.com/yamoling/lle"
},
"split_keywords": [
"marl",
" rl",
" lle",
" laser",
" environment"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "96b28b4689301b20904ae8a00d8b7a651f1a6edc13aa0157e1f6b102f5a6adaa",
"md5": "f7707ee5a4d03ac9d8e5df417b8e4ffc",
"sha256": "7271c933c3f5c61bd244da6e39fcf9dd68b34c581313835d04d6568290862aac"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp311-cp311-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "f7707ee5a4d03ac9d8e5df417b8e4ffc",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "<4,>=3.11",
"size": 1426824,
"upload_time": "2024-11-21T14:54:08",
"upload_time_iso_8601": "2024-11-21T14:54:08.336567Z",
"url": "https://files.pythonhosted.org/packages/96/b2/8b4689301b20904ae8a00d8b7a651f1a6edc13aa0157e1f6b102f5a6adaa/laser_learning_environment-2.0.0-cp311-cp311-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "673ce703a2c3af30ea97e8110afaf6a4962149b1e2acd514b59c04b8340a2468",
"md5": "b39fd845a467dc00d16ad0eef564ee74",
"sha256": "c09492e310f3660bae07cf89e4ae9c069bc61af33003d54e2e75a0f91982666a"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp311-cp311-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "b39fd845a467dc00d16ad0eef564ee74",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "<4,>=3.11",
"size": 1376710,
"upload_time": "2024-11-21T14:54:04",
"upload_time_iso_8601": "2024-11-21T14:54:04.672141Z",
"url": "https://files.pythonhosted.org/packages/67/3c/e703a2c3af30ea97e8110afaf6a4962149b1e2acd514b59c04b8340a2468/laser_learning_environment-2.0.0-cp311-cp311-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c90f9fd1e19a0057cccd3ecb05c313312938ddb44ba61ad734cd0f57d3bac70a",
"md5": "6fcc2c906e4884e4d2d7476a215ec138",
"sha256": "20acaf8f2f720d07a789fd5a8cb1481c738d1183a1c541e279d2cc291ca3094e"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "6fcc2c906e4884e4d2d7476a215ec138",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "<4,>=3.11",
"size": 1525973,
"upload_time": "2024-11-21T14:54:12",
"upload_time_iso_8601": "2024-11-21T14:54:12.658581Z",
"url": "https://files.pythonhosted.org/packages/c9/0f/9fd1e19a0057cccd3ecb05c313312938ddb44ba61ad734cd0f57d3bac70a/laser_learning_environment-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "612a8a1abef0bab1857b68ca598cc7642b435900c5bc76b02711ddbd4d727209",
"md5": "38ae9727a0ac1515559952c4ac8076d1",
"sha256": "0497a0adb171fd1f30ebd2fbc3349bf45c5792ac65422e26782dbfe3e40f69f0"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "38ae9727a0ac1515559952c4ac8076d1",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "<4,>=3.11",
"size": 1552921,
"upload_time": "2024-11-21T14:54:16",
"upload_time_iso_8601": "2024-11-21T14:54:16.108670Z",
"url": "https://files.pythonhosted.org/packages/61/2a/8a1abef0bab1857b68ca598cc7642b435900c5bc76b02711ddbd4d727209/laser_learning_environment-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "00a07c641c4b8712433577dda28ea8c07f391538cb86457279c4010918598242",
"md5": "571f3056df4e5c1d6c98190dc0c9e680",
"sha256": "d6fbd06c0dbb43f74e60d7664d2a4ae53ee76b7cb306877946081e860ee688f8"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp311-none-win_amd64.whl",
"has_sig": false,
"md5_digest": "571f3056df4e5c1d6c98190dc0c9e680",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": "<4,>=3.11",
"size": 1243665,
"upload_time": "2024-11-21T14:54:19",
"upload_time_iso_8601": "2024-11-21T14:54:19.574359Z",
"url": "https://files.pythonhosted.org/packages/00/a0/7c641c4b8712433577dda28ea8c07f391538cb86457279c4010918598242/laser_learning_environment-2.0.0-cp311-none-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "22b6cc6a76386f05e0a5de9101748ef2d51ec2d4f72807673f1f617d1ee0b906",
"md5": "6f5989d52bf8021f40d90b6f978efbf1",
"sha256": "2361df85bd6b00936733fdb808c02430609bbcd860fc56fb1b1590a1d114f330"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp312-cp312-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "6f5989d52bf8021f40d90b6f978efbf1",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": "<4,>=3.11",
"size": 1421802,
"upload_time": "2024-11-21T14:54:10",
"upload_time_iso_8601": "2024-11-21T14:54:10.346210Z",
"url": "https://files.pythonhosted.org/packages/22/b6/cc6a76386f05e0a5de9101748ef2d51ec2d4f72807673f1f617d1ee0b906/laser_learning_environment-2.0.0-cp312-cp312-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f84af20d3d22d2b6db46930d5576cc23be286bca0b5991182aa3fe64b8c2de69",
"md5": "32ef2ae2a5e171ea3a2871ced10ac87b",
"sha256": "b70447d2184742b5122d998e0ab05694bebd4213aa0494f3b6373ec3f5308913"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp312-cp312-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "32ef2ae2a5e171ea3a2871ced10ac87b",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": "<4,>=3.11",
"size": 1383756,
"upload_time": "2024-11-21T14:54:07",
"upload_time_iso_8601": "2024-11-21T14:54:07.015168Z",
"url": "https://files.pythonhosted.org/packages/f8/4a/f20d3d22d2b6db46930d5576cc23be286bca0b5991182aa3fe64b8c2de69/laser_learning_environment-2.0.0-cp312-cp312-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "9b02198d2fdb6d9b4cc6a85b71ab183a9d9704a8d828647f016203727c7f4e51",
"md5": "68895e11403061cd643eacdc005d04a4",
"sha256": "feea91a52bc645d7131c97a85d96073bfb52efe1f16617b31fdd2b8ef1828ba2"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "68895e11403061cd643eacdc005d04a4",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": "<4,>=3.11",
"size": 1526379,
"upload_time": "2024-11-21T14:54:14",
"upload_time_iso_8601": "2024-11-21T14:54:14.734970Z",
"url": "https://files.pythonhosted.org/packages/9b/02/198d2fdb6d9b4cc6a85b71ab183a9d9704a8d828647f016203727c7f4e51/laser_learning_environment-2.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "fbc608a4ca0b65b8a435e262a7515ab0b25c35098f27ab2f506f2423e2573494",
"md5": "b33850aaa58d6f2654853b83f215198d",
"sha256": "7c2d89b43b856fd8b2866941730d9b6c292fe799d0a9341833cb55376143d075"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "b33850aaa58d6f2654853b83f215198d",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": "<4,>=3.11",
"size": 1556464,
"upload_time": "2024-11-21T14:54:17",
"upload_time_iso_8601": "2024-11-21T14:54:17.529799Z",
"url": "https://files.pythonhosted.org/packages/fb/c6/08a4ca0b65b8a435e262a7515ab0b25c35098f27ab2f506f2423e2573494/laser_learning_environment-2.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "609a6e50a7af7cd41b74177c976945133a3c6010c3397f64fdcbb7769a9caef3",
"md5": "52f57c9356a5575116f358ffbf1ad46c",
"sha256": "280a8424cc6882348c474c03daf3c7a98e0f295c2c4a7d4f22f4917f547a12dd"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0-cp312-none-win_amd64.whl",
"has_sig": false,
"md5_digest": "52f57c9356a5575116f358ffbf1ad46c",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": "<4,>=3.11",
"size": 1242803,
"upload_time": "2024-11-21T14:54:21",
"upload_time_iso_8601": "2024-11-21T14:54:21.027746Z",
"url": "https://files.pythonhosted.org/packages/60/9a/6e50a7af7cd41b74177c976945133a3c6010c3397f64fdcbb7769a9caef3/laser_learning_environment-2.0.0-cp312-none-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e09492e73a737aa11858efa3d031f1a740bcfc82046d728018b70401c8b39288",
"md5": "053692e5a66ebcf5ad2d7171795c03d3",
"sha256": "0ced5d7a04df0fd2ac7227de7b3369a7590e7b8b47883534c1018cf7014c18b0"
},
"downloads": -1,
"filename": "laser_learning_environment-2.0.0.tar.gz",
"has_sig": false,
"md5_digest": "053692e5a66ebcf5ad2d7171795c03d3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4,>=3.11",
"size": 95622,
"upload_time": "2024-11-21T14:54:11",
"upload_time_iso_8601": "2024-11-21T14:54:11.668654Z",
"url": "https://files.pythonhosted.org/packages/e0/94/92e73a737aa11858efa3d031f1a740bcfc82046d728018b70401c8b39288/laser_learning_environment-2.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-21 14:54:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yamoling",
"github_project": "lle",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "laser-learning-environment"
}