mettagrid 0.2__tar.gz → 0.2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mettagrid might be problematic. Click here for more details.
- {mettagrid-0.2 → mettagrid-0.2.0.2}/PKG-INFO +3 -3
- {mettagrid-0.2 → mettagrid-0.2.0.2}/bazel_build.py +17 -6
- {mettagrid-0.2 → mettagrid-0.2.0.2}/pyproject.toml +4 -4
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/get_output.hpp +1 -31
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/builder/envs.py +4 -4
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/grid.hpp +0 -27
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_c.cpp +0 -29
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_c.pyi +2 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_c_config.py +1 -12
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_config.hpp +7 -3
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_config.py +4 -11
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_env.py +44 -1
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/agent.hpp +1 -4
- mettagrid-0.2.0.2/src/metta/mettagrid/util/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/util/file.py +25 -11
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/mettagrid.egg-info/PKG-INFO +3 -3
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/mettagrid.egg-info/SOURCES.txt +1 -4
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/mettagrid.egg-info/requires.txt +1 -1
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_action_compatibility.py +8 -9
- mettagrid-0.2/MODULE.bazel.lock +0 -809
- mettagrid-0.2/src/metta/mettagrid/actions/place_box.hpp +0 -41
- mettagrid-0.2/src/metta/mettagrid/mettagrid_c.so +0 -0
- mettagrid-0.2/src/metta/mettagrid/objects/box.hpp +0 -51
- {mettagrid-0.2 → mettagrid-0.2.0.2}/.bazelrc +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/BUILD.bazel +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/LICENSE +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/MANIFEST.in +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/MODULE.bazel +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/README.md +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/setup.cfg +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/action_handler.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/attack.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/change_color.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/change_glyph.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/move.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/noop.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/orientation.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/put_recipe_items.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/rotate.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/actions/swap.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/builder/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/builder/building.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/builder/empty_converters.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/char_encoder.py +0 -0
- /mettagrid-0.2/src/metta/mettagrid/mapgen/__init__.py → /mettagrid-0.2.0.2/src/metta/mettagrid/config/config.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/config.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/core.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/episode_stats_db.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/event.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/grid_object.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/grid_object_formatter.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/gym_env.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/gym_wrapper.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/hash.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/ascii.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/map_builder.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/maze.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/perimeter_incontext.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/random.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/map_builder/utils.py +0 -0
- {mettagrid-0.2/src/metta/mettagrid/objects → mettagrid-0.2.0.2/src/metta/mettagrid/mapgen}/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/load.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/mapgen.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/mapgen_ascii.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/random/float.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/random/int.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scene.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/ascii.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/auto.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/bsp.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/convchain.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/copy_grid.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/grid_altars.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/inline_ascii.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/layout.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/make_connected.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/maze.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/mean_distance.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/mirror.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/multi_left_and_right.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/nop.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/radial_maze.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/random.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/random_dcss_scene.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/random_objects.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/random_scene.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/random_yaml_scene.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/remove_agents.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/room_grid.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/spiral.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/transplant_scene.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/varied_terrain.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/wfc.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/scenes/yaml.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/tools/dcss_import.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/tools/gen.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/tools/gen_scene.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/tools/view.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/types.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/ascii_grid.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/draw.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/make_scene_config.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/pattern.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/s3utils.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/show.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/storable_map.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/storable_map_index.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mapgen/utils/thumbnail.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/mettagrid_c.hpp +0 -0
- {mettagrid-0.2/src/metta/mettagrid/util → mettagrid-0.2.0.2/src/metta/mettagrid/objects}/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/agent_config.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/constants.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/converter.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/converter_config.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/has_inventory.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/production_handler.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/objects/wall.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/observation_encoder.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/packed_coordinate.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/pettingzoo_env.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/profiling/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/profiling/memory_monitor.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/profiling/stopwatch.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/profiling/system_monitor.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/puffer_base.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/py.typed +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/renderer/hermes.cpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/renderer/hermes.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/renderer/hermes.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/renderer/miniscope.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/renderer/nethack.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/replay_writer.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/stats_tracker.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/stats_writer.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/test_support/__init__.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/test_support/actions.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/test_support/mapgen.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/test_support/observation_helper.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/test_support/orientation.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/test_support/token_types.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/types.hpp +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/util/debug.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/util/dict_utils.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/util/diversity.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/metta/mettagrid/util/module.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/mettagrid.egg-info/dependency_links.txt +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/src/mettagrid.egg-info/top_level.txt +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_actions.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_attack_resource_exception.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_buffer_reuse.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_buffers.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_converter.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_diversity.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_env_config_serialization.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_env_map.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_forbidden_imports.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_gdrive.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_global_obs_config.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_global_observations.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_global_reward_observations.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_gym_env.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_interactive.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_leaks.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_mettagrid.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_move.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_new_env_hierarchy.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_observations.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_pettingzoo_env.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_pufferlib_integration.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_resource_loss.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_rewards.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_rotate.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_stats_rewards.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_stats_writer.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_swap.py +0 -0
- {mettagrid-0.2 → mettagrid-0.2.0.2}/tests/test_visitation_counts.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mettagrid
|
|
3
|
-
Version: 0.2
|
|
3
|
+
Version: 0.2.0.2
|
|
4
4
|
Summary: A fast grid-based open-ended MARL environment
|
|
5
5
|
Author-email: David Bloomin <daveey@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://daveey.github.io
|
|
8
8
|
Project-URL: Repository, https://github.com/Metta-AI/mettagrid
|
|
9
9
|
Keywords: gridworld,minigrid,rl,reinforcement-learning,environment,gym
|
|
10
|
-
Requires-Python:
|
|
10
|
+
Requires-Python: <3.12,>=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
Requires-Dist: boto3>=1.38.32
|
|
@@ -18,7 +18,7 @@ Requires-Dist: google-auth-oauthlib>=1.0.0
|
|
|
18
18
|
Requires-Dist: gymnasium==0.29.1
|
|
19
19
|
Requires-Dist: matplotlib>=3.10.3
|
|
20
20
|
Requires-Dist: numpy<2,>=1.26.4
|
|
21
|
-
Requires-Dist: omegaconf>=2.
|
|
21
|
+
Requires-Dist: omegaconf>=2.3.0
|
|
22
22
|
Requires-Dist: duckdb>=1.3.0
|
|
23
23
|
Requires-Dist: pettingzoo<1.25,>=1.24.1
|
|
24
24
|
Requires-Dist: pufferlib<3.1.0,>=3.0.0
|
|
@@ -23,6 +23,7 @@ from setuptools.build_meta import (
|
|
|
23
23
|
prepare_metadata_for_build_editable,
|
|
24
24
|
prepare_metadata_for_build_wheel,
|
|
25
25
|
)
|
|
26
|
+
from setuptools.dist import Distribution
|
|
26
27
|
|
|
27
28
|
PROJECT_ROOT = Path(__file__).resolve().parent
|
|
28
29
|
|
|
@@ -31,9 +32,7 @@ def _run_bazel_build() -> None:
|
|
|
31
32
|
"""Run Bazel build to compile the C++ extension."""
|
|
32
33
|
# Check if bazel is available
|
|
33
34
|
if shutil.which("bazel") is None:
|
|
34
|
-
raise RuntimeError(
|
|
35
|
-
"Bazel is required to build metta-mettagrid. Please install Bazel: https://bazel.build/install"
|
|
36
|
-
)
|
|
35
|
+
raise RuntimeError("Bazel is required to build mettagrid. Please install Bazel: https://bazel.build/install")
|
|
37
36
|
|
|
38
37
|
# Determine build configuration from environment
|
|
39
38
|
debug = os.environ.get("DEBUG", "").lower() in ("1", "true", "yes")
|
|
@@ -47,11 +46,13 @@ def _run_bazel_build() -> None:
|
|
|
47
46
|
else:
|
|
48
47
|
config = "dbg" if debug else "opt"
|
|
49
48
|
|
|
50
|
-
# Build the Python extension
|
|
49
|
+
# Build the Python extension with auto-detected parallelism
|
|
51
50
|
cmd = [
|
|
52
51
|
"bazel",
|
|
53
52
|
"build",
|
|
54
53
|
f"--config={config}",
|
|
54
|
+
"--jobs=auto",
|
|
55
|
+
"--verbose_failures",
|
|
55
56
|
"//:mettagrid_c",
|
|
56
57
|
]
|
|
57
58
|
|
|
@@ -59,7 +60,10 @@ def _run_bazel_build() -> None:
|
|
|
59
60
|
result = subprocess.run(cmd, cwd=PROJECT_ROOT, capture_output=True, text=True)
|
|
60
61
|
|
|
61
62
|
if result.returncode != 0:
|
|
62
|
-
print(
|
|
63
|
+
print("Bazel build failed. STDERR:", file=sys.stderr)
|
|
64
|
+
print(result.stderr, file=sys.stderr)
|
|
65
|
+
print("Bazel build STDOUT:", file=sys.stderr)
|
|
66
|
+
print(result.stdout, file=sys.stderr)
|
|
63
67
|
raise RuntimeError("Bazel build failed")
|
|
64
68
|
|
|
65
69
|
# Copy the built extension to the package directory
|
|
@@ -92,7 +96,14 @@ def _run_bazel_build() -> None:
|
|
|
92
96
|
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
|
|
93
97
|
"""Build a wheel, compiling the C++ extension with Bazel first."""
|
|
94
98
|
_run_bazel_build()
|
|
95
|
-
|
|
99
|
+
# Ensure wheel is tagged as non-pure (platform-specific) since we bundle a native extension
|
|
100
|
+
# Setuptools/wheel derive purity from Distribution.has_ext_modules(). Monkeypatch to force True.
|
|
101
|
+
original_has_ext_modules = Distribution.has_ext_modules
|
|
102
|
+
try:
|
|
103
|
+
Distribution.has_ext_modules = lambda self: True # type: ignore[assignment]
|
|
104
|
+
return _build_wheel(wheel_directory, config_settings, metadata_directory)
|
|
105
|
+
finally:
|
|
106
|
+
Distribution.has_ext_modules = original_has_ext_modules
|
|
96
107
|
|
|
97
108
|
|
|
98
109
|
def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
|
|
@@ -4,11 +4,11 @@ build-backend = "bazel_build"
|
|
|
4
4
|
backend-path = ["."]
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
|
-
name = "mettagrid"
|
|
8
|
-
version = "0.2"
|
|
7
|
+
name = "mettagrid" # Do not change! Has to be 'mettagrid' for our PyPi package
|
|
8
|
+
version = "0.2.0.2"
|
|
9
9
|
description = "A fast grid-based open-ended MARL environment"
|
|
10
10
|
authors = [{ name = "David Bloomin", email = "daveey@gmail.com" }]
|
|
11
|
-
requires-python = "
|
|
11
|
+
requires-python = ">=3.11,<3.12"
|
|
12
12
|
license = "MIT"
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
urls = { Homepage = "https://daveey.github.io", Repository = "https://github.com/Metta-AI/mettagrid" }
|
|
@@ -29,7 +29,7 @@ dependencies = [
|
|
|
29
29
|
"gymnasium==0.29.1",
|
|
30
30
|
"matplotlib>=3.10.3",
|
|
31
31
|
"numpy>=1.26.4,<2",
|
|
32
|
-
"omegaconf>=2.
|
|
32
|
+
"omegaconf>=2.3.0",
|
|
33
33
|
"duckdb>=1.3.0",
|
|
34
34
|
"pettingzoo>=1.24.1,<1.25",
|
|
35
35
|
"pufferlib>=3.0.0,<3.1.0",
|
|
@@ -26,11 +26,7 @@ protected:
|
|
|
26
26
|
// Once we generalize this to `get`, we should be able to get from any HasInventory object, which
|
|
27
27
|
// should include agents. That's (e.g.) why we're checking inventory_is_accessible.
|
|
28
28
|
Converter* converter = dynamic_cast<Converter*>(_grid->object_at(target_loc));
|
|
29
|
-
|
|
30
|
-
if (!converter && !box) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
// If converter, get output from converter
|
|
29
|
+
|
|
34
30
|
if (converter) {
|
|
35
31
|
if (!converter->inventory_is_accessible()) {
|
|
36
32
|
return false;
|
|
@@ -55,32 +51,6 @@ protected:
|
|
|
55
51
|
}
|
|
56
52
|
return resources_taken;
|
|
57
53
|
}
|
|
58
|
-
|
|
59
|
-
// If box, pick up box if allowed
|
|
60
|
-
if (box) {
|
|
61
|
-
if (actor->agent_id == box->creator_agent_id) {
|
|
62
|
-
// Creator cannot open their own box
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
// If the creator of the box is an agent, return blue battery to creator and penalize creator
|
|
66
|
-
if (box->creator_agent_id != 255) {
|
|
67
|
-
Agent* creator = dynamic_cast<Agent*>(_grid->object(box->creator_agent_object_id));
|
|
68
|
-
if (!creator) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
// Return required resources to create box to creator inventory
|
|
72
|
-
for (const auto& [item, amount] : box->returned_resources) {
|
|
73
|
-
if (amount > 0) {
|
|
74
|
-
creator->update_inventory(item, amount);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Reward the agent for opening the box and teleport back to top-left corner
|
|
80
|
-
_grid->ghost_move_object(box->id, GridLocation(0, 0, GridLayer::ObjectLayer));
|
|
81
|
-
actor->stats.add("box.opened", 1.0f);
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
54
|
return false;
|
|
85
55
|
}
|
|
86
56
|
};
|
|
@@ -112,7 +112,7 @@ def make_navigation(num_agents: int) -> MettaGridConfig:
|
|
|
112
112
|
resource_names=["heart"],
|
|
113
113
|
actions=ActionsConfig(
|
|
114
114
|
move=ActionConfig(),
|
|
115
|
-
rotate=ActionConfig(),
|
|
115
|
+
rotate=ActionConfig(enabled=False),
|
|
116
116
|
get_items=ActionConfig(),
|
|
117
117
|
),
|
|
118
118
|
agent=AgentConfig(
|
|
@@ -149,7 +149,7 @@ def make_navigation_sequence(num_agents: int) -> MettaGridConfig:
|
|
|
149
149
|
resource_names=["heart", "ore_red", "battery_red"],
|
|
150
150
|
actions=ActionsConfig(
|
|
151
151
|
move=ActionConfig(),
|
|
152
|
-
rotate=ActionConfig(),
|
|
152
|
+
rotate=ActionConfig(enabled=False),
|
|
153
153
|
get_items=ActionConfig(),
|
|
154
154
|
),
|
|
155
155
|
agent=AgentConfig(
|
|
@@ -173,7 +173,7 @@ def make_navigation_sequence(num_agents: int) -> MettaGridConfig:
|
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
def make_icl_resource_chain(
|
|
176
|
-
num_agents: int, max_steps, game_objects: dict, map_builder_objects: dict
|
|
176
|
+
num_agents: int, max_steps, game_objects: dict, map_builder_objects: dict, width: int = 6, height: int = 6
|
|
177
177
|
) -> MettaGridConfig:
|
|
178
178
|
game_objects["wall"] = empty_converters.wall
|
|
179
179
|
cfg = MettaGridConfig(
|
|
@@ -184,7 +184,7 @@ def make_icl_resource_chain(
|
|
|
184
184
|
map_builder=MapGen.Config(
|
|
185
185
|
instances=num_agents,
|
|
186
186
|
instance_map=PerimeterInContextMapBuilder.Config(
|
|
187
|
-
agents=1, width=
|
|
187
|
+
agents=1, width=width, height=height, objects=map_builder_objects
|
|
188
188
|
),
|
|
189
189
|
),
|
|
190
190
|
actions=ActionsConfig(
|
|
@@ -69,15 +69,6 @@ public:
|
|
|
69
69
|
return true;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
inline bool ghost_add_object(GridObject* obj) {
|
|
73
|
-
if (!is_valid_location(obj->location)) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
obj->id = static_cast<GridObjectId>(this->objects.size());
|
|
77
|
-
this->objects.push_back(std::unique_ptr<GridObject>(obj));
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
72
|
// Removes an object from the grid and gives ownership of the object to the caller.
|
|
82
73
|
// Since the caller is now the owner, this can make the raw pointer invalid, if the
|
|
83
74
|
// returned unique_ptr is destroyed.
|
|
@@ -104,24 +95,6 @@ public:
|
|
|
104
95
|
return true;
|
|
105
96
|
}
|
|
106
97
|
|
|
107
|
-
// Force move an object to a location without it being registered in the grid at the new location
|
|
108
|
-
inline bool ghost_move_object(GridObjectId id, const GridLocation& loc) {
|
|
109
|
-
if (!is_valid_location(loc)) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
GridObject* obj = object(id);
|
|
114
|
-
if (!obj) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Remove the object from its current location
|
|
119
|
-
grid[obj->location.r][obj->location.c][obj->location.layer] = 0;
|
|
120
|
-
|
|
121
|
-
obj->location = loc;
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
98
|
inline void swap_objects(GridObjectId id1, GridObjectId id2) {
|
|
126
99
|
GridObject* obj1 = object(id1);
|
|
127
100
|
GridObject* obj2 = object(id2);
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
#include "actions/get_output.hpp"
|
|
17
17
|
#include "actions/move.hpp"
|
|
18
18
|
#include "actions/noop.hpp"
|
|
19
|
-
#include "actions/place_box.hpp"
|
|
20
19
|
#include "actions/put_recipe_items.hpp"
|
|
21
20
|
#include "actions/rotate.hpp"
|
|
22
21
|
#include "actions/swap.hpp"
|
|
@@ -24,7 +23,6 @@
|
|
|
24
23
|
#include "grid.hpp"
|
|
25
24
|
#include "hash.hpp"
|
|
26
25
|
#include "objects/agent.hpp"
|
|
27
|
-
#include "objects/box.hpp"
|
|
28
26
|
#include "objects/constants.hpp"
|
|
29
27
|
#include "objects/converter.hpp"
|
|
30
28
|
#include "objects/converter_config.hpp"
|
|
@@ -85,8 +83,6 @@ MettaGrid::MettaGrid(const GameConfig& game_config, const py::list map, unsigned
|
|
|
85
83
|
for (const auto& [action_name, action_config] : game_config.actions) {
|
|
86
84
|
if (action_name == "put_items") {
|
|
87
85
|
_action_handlers.push_back(std::make_unique<PutRecipeItems>(*action_config));
|
|
88
|
-
} else if (action_name == "place_box") {
|
|
89
|
-
_action_handlers.push_back(std::make_unique<PlaceBox>(*action_config));
|
|
90
86
|
} else if (action_name == "get_items") {
|
|
91
87
|
_action_handlers.push_back(std::make_unique<GetOutput>(*action_config));
|
|
92
88
|
} else if (action_name == "noop") {
|
|
@@ -168,14 +164,6 @@ MettaGrid::MettaGrid(const GameConfig& game_config, const py::list map, unsigned
|
|
|
168
164
|
continue;
|
|
169
165
|
}
|
|
170
166
|
|
|
171
|
-
const BoxConfig* box_config = dynamic_cast<const BoxConfig*>(object_cfg);
|
|
172
|
-
if (box_config) {
|
|
173
|
-
Box* box = new Box(r, c, *box_config, 255, 255); // Default creator values
|
|
174
|
-
_grid->add_object(box);
|
|
175
|
-
_stats->incr("objects." + cell);
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
167
|
const ConverterConfig* converter_config = dynamic_cast<const ConverterConfig*>(object_cfg);
|
|
180
168
|
if (converter_config) {
|
|
181
169
|
// Create a new ConverterConfig with the recipe offsets from the observation encoder
|
|
@@ -204,14 +192,6 @@ MettaGrid::MettaGrid(const GameConfig& game_config, const py::list map, unsigned
|
|
|
204
192
|
if (_global_obs_config.visitation_counts) {
|
|
205
193
|
agent->init_visitation_grid(height, width);
|
|
206
194
|
}
|
|
207
|
-
// add agent box
|
|
208
|
-
if (game_config.objects.contains("box")) {
|
|
209
|
-
const BoxConfig* local_box_cfg = dynamic_cast<const BoxConfig*>(game_config.objects.at("box").get());
|
|
210
|
-
if (local_box_cfg) {
|
|
211
|
-
agent->box = new Box(0, 0, *local_box_cfg, agent->id, static_cast<unsigned char>(agent->agent_id));
|
|
212
|
-
_grid->ghost_add_object(agent->box);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
195
|
add_agent(agent);
|
|
216
196
|
_group_sizes[agent->group] += 1;
|
|
217
197
|
continue;
|
|
@@ -929,15 +909,6 @@ PYBIND11_MODULE(mettagrid_c, m) {
|
|
|
929
909
|
|
|
930
910
|
bind_wall_config(m);
|
|
931
911
|
|
|
932
|
-
py::class_<BoxConfig, GridObjectConfig, std::shared_ptr<BoxConfig>>(m, "BoxConfig")
|
|
933
|
-
.def(py::init<TypeId, const std::string&, const std::map<InventoryItem, InventoryQuantity>&>(),
|
|
934
|
-
py::arg("type_id"),
|
|
935
|
-
py::arg("type_name") = "box",
|
|
936
|
-
py::arg("returned_resources"))
|
|
937
|
-
.def_readwrite("type_id", &BoxConfig::type_id)
|
|
938
|
-
.def_readwrite("type_name", &BoxConfig::type_name)
|
|
939
|
-
.def_readwrite("returned_resources", &BoxConfig::returned_resources);
|
|
940
|
-
|
|
941
912
|
// ##MettaGridConfig
|
|
942
913
|
// We expose these as much as we can to Python. Defining the initializer (and the object's constructor) means
|
|
943
914
|
// we can create these in Python as AgentConfig(**agent_config_dict). And then we expose the fields individually.
|
|
@@ -186,6 +186,7 @@ class GameConfig:
|
|
|
186
186
|
track_movement_metrics: bool = False,
|
|
187
187
|
recipe_details_obs: bool = False,
|
|
188
188
|
allow_diagonals: bool = False,
|
|
189
|
+
reward_estimates: Optional[dict[str, float]] = None,
|
|
189
190
|
) -> None: ...
|
|
190
191
|
num_agents: int
|
|
191
192
|
max_steps: int
|
|
@@ -200,6 +201,7 @@ class GameConfig:
|
|
|
200
201
|
track_movement_metrics: bool
|
|
201
202
|
recipe_details_obs: bool
|
|
202
203
|
allow_diagonals: bool
|
|
204
|
+
reward_estimates: Optional[dict[str, float]]
|
|
203
205
|
|
|
204
206
|
class MettaGrid:
|
|
205
207
|
obs_width: int
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
from metta.mettagrid.mettagrid_c import ActionConfig as CppActionConfig
|
|
2
2
|
from metta.mettagrid.mettagrid_c import AgentConfig as CppAgentConfig
|
|
3
3
|
from metta.mettagrid.mettagrid_c import AttackActionConfig as CppAttackActionConfig
|
|
4
|
-
from metta.mettagrid.mettagrid_c import BoxConfig as CppBoxConfig
|
|
5
4
|
from metta.mettagrid.mettagrid_c import ChangeGlyphActionConfig as CppChangeGlyphActionConfig
|
|
6
5
|
from metta.mettagrid.mettagrid_c import ConverterConfig as CppConverterConfig
|
|
7
6
|
from metta.mettagrid.mettagrid_c import GameConfig as CppGameConfig
|
|
8
7
|
from metta.mettagrid.mettagrid_c import GlobalObsConfig as CppGlobalObsConfig
|
|
9
8
|
from metta.mettagrid.mettagrid_c import WallConfig as CppWallConfig
|
|
10
|
-
from metta.mettagrid.mettagrid_config import AgentConfig,
|
|
9
|
+
from metta.mettagrid.mettagrid_config import AgentConfig, ConverterConfig, GameConfig, WallConfig
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
def recursive_update(d, u):
|
|
@@ -156,16 +155,6 @@ def convert_to_cpp_game_config(mettagrid_config: dict | GameConfig):
|
|
|
156
155
|
swappable=object_config.swappable,
|
|
157
156
|
)
|
|
158
157
|
objects_cpp_params[object_type] = cpp_wall_config
|
|
159
|
-
elif isinstance(object_config, BoxConfig):
|
|
160
|
-
returned_resources = game_config.actions.place_box.consumed_resources
|
|
161
|
-
cpp_box_config = CppBoxConfig(
|
|
162
|
-
type_id=object_config.type_id,
|
|
163
|
-
type_name=object_type,
|
|
164
|
-
returned_resources={
|
|
165
|
-
resource_name_to_id[k]: v for k, v in returned_resources.items() if k in resource_name_to_id
|
|
166
|
-
},
|
|
167
|
-
)
|
|
168
|
-
objects_cpp_params[object_type] = cpp_box_config
|
|
169
158
|
else:
|
|
170
159
|
raise ValueError(f"Unknown object type: {object_type}")
|
|
171
160
|
|
|
@@ -42,6 +42,7 @@ struct GameConfig {
|
|
|
42
42
|
bool track_movement_metrics = false;
|
|
43
43
|
bool recipe_details_obs = false;
|
|
44
44
|
bool allow_diagonals = false;
|
|
45
|
+
std::map<std::string, float> reward_estimates = {};
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
namespace py = pybind11;
|
|
@@ -79,7 +80,8 @@ inline void bind_game_config(py::module& m) {
|
|
|
79
80
|
// FEATURE FLAGS
|
|
80
81
|
bool,
|
|
81
82
|
bool,
|
|
82
|
-
bool
|
|
83
|
+
bool,
|
|
84
|
+
const std::map<std::string, float>&>(),
|
|
83
85
|
py::arg("num_agents"),
|
|
84
86
|
py::arg("max_steps"),
|
|
85
87
|
py::arg("episode_truncates"),
|
|
@@ -95,7 +97,8 @@ inline void bind_game_config(py::module& m) {
|
|
|
95
97
|
// FEATURE FLAGS
|
|
96
98
|
py::arg("track_movement_metrics"),
|
|
97
99
|
py::arg("recipe_details_obs") = false,
|
|
98
|
-
py::arg("allow_diagonals") = false
|
|
100
|
+
py::arg("allow_diagonals") = false,
|
|
101
|
+
py::arg("reward_estimates") = std::map<std::string, float>())
|
|
99
102
|
.def_readwrite("num_agents", &GameConfig::num_agents)
|
|
100
103
|
.def_readwrite("max_steps", &GameConfig::max_steps)
|
|
101
104
|
.def_readwrite("episode_truncates", &GameConfig::episode_truncates)
|
|
@@ -116,7 +119,8 @@ inline void bind_game_config(py::module& m) {
|
|
|
116
119
|
// FEATURE FLAGS
|
|
117
120
|
.def_readwrite("track_movement_metrics", &GameConfig::track_movement_metrics)
|
|
118
121
|
.def_readwrite("recipe_details_obs", &GameConfig::recipe_details_obs)
|
|
119
|
-
.def_readwrite("allow_diagonals", &GameConfig::allow_diagonals)
|
|
122
|
+
.def_readwrite("allow_diagonals", &GameConfig::allow_diagonals)
|
|
123
|
+
.def_readwrite("reward_estimates", &GameConfig::reward_estimates);
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
#endif // METTAGRID_CONFIG_HPP_
|
|
@@ -74,8 +74,7 @@ class ActionsConfig(Config):
|
|
|
74
74
|
noop: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=False))
|
|
75
75
|
move: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=True)) # Default movement action
|
|
76
76
|
rotate: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=False))
|
|
77
|
-
put_items: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=
|
|
78
|
-
place_box: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=False))
|
|
77
|
+
put_items: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=True))
|
|
79
78
|
get_items: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=True))
|
|
80
79
|
attack: AttackActionConfig = Field(default_factory=lambda: AttackActionConfig(enabled=False))
|
|
81
80
|
swap: ActionConfig = Field(default_factory=lambda: ActionConfig(enabled=False))
|
|
@@ -107,14 +106,6 @@ class WallConfig(Config):
|
|
|
107
106
|
swappable: bool = Field(default=False)
|
|
108
107
|
|
|
109
108
|
|
|
110
|
-
class BoxConfig(Config):
|
|
111
|
-
"""Python box configuration."""
|
|
112
|
-
|
|
113
|
-
type_id: int = Field(default=0, ge=0, le=255)
|
|
114
|
-
# We don't allow setting of returned_resources -- it should always match
|
|
115
|
-
# the consumed_resources by place_box.
|
|
116
|
-
|
|
117
|
-
|
|
118
109
|
class ConverterConfig(Config):
|
|
119
110
|
"""Python converter configuration."""
|
|
120
111
|
|
|
@@ -160,7 +151,7 @@ class GameConfig(Config):
|
|
|
160
151
|
agents: list[AgentConfig] = Field(default_factory=list)
|
|
161
152
|
actions: ActionsConfig = Field(default_factory=lambda: ActionsConfig(noop=ActionConfig()))
|
|
162
153
|
global_obs: GlobalObsConfig = Field(default_factory=GlobalObsConfig)
|
|
163
|
-
objects: dict[str, ConverterConfig | WallConfig
|
|
154
|
+
objects: dict[str, ConverterConfig | WallConfig] = Field(default_factory=dict)
|
|
164
155
|
# these are not used in the C++ code, but we allow them to be set for other uses.
|
|
165
156
|
# E.g., templates can use params as a place where values are expected to be written,
|
|
166
157
|
# and other parts of the template can read from there.
|
|
@@ -180,6 +171,8 @@ class GameConfig(Config):
|
|
|
180
171
|
)
|
|
181
172
|
allow_diagonals: bool = Field(default=False, description="Enable actions to be aware of diagonal orientations")
|
|
182
173
|
|
|
174
|
+
reward_estimates: Optional[dict[str, float]] = Field(default=None)
|
|
175
|
+
|
|
183
176
|
|
|
184
177
|
class MettaGridConfig(Config):
|
|
185
178
|
"""Environment configuration."""
|
|
@@ -59,6 +59,8 @@ class MettaGridEnv(MettaGridPufferBase):
|
|
|
59
59
|
self._episode_id: str | None = None
|
|
60
60
|
self._last_reset_ts = datetime.datetime.now()
|
|
61
61
|
self._is_training = is_training
|
|
62
|
+
self._label_completions = {"completed_tasks": [], "completion_rates": {}}
|
|
63
|
+
self.per_label_rewards = {}
|
|
62
64
|
|
|
63
65
|
# DesyncEpisodes - when training we want to stagger experience. The first episode
|
|
64
66
|
# will end early so that the next episode can begin at a different time on each worker.
|
|
@@ -125,7 +127,25 @@ class MettaGridEnv(MettaGridPufferBase):
|
|
|
125
127
|
self.timer.start("thread_idle")
|
|
126
128
|
return observations, rewards, terminals, truncations, infos
|
|
127
129
|
|
|
128
|
-
def
|
|
130
|
+
def _update_label_completions(self, moving_avg_window: int = 500) -> None:
|
|
131
|
+
"""Update label completions."""
|
|
132
|
+
label = self.mg_config.label
|
|
133
|
+
|
|
134
|
+
# keep track of a list of the last 500 labels
|
|
135
|
+
if len(self._label_completions["completed_tasks"]) >= moving_avg_window:
|
|
136
|
+
self._label_completions["completed_tasks"].pop(0)
|
|
137
|
+
self._label_completions["completed_tasks"].append(label)
|
|
138
|
+
|
|
139
|
+
# moving average of the completion rates
|
|
140
|
+
self._label_completions["completion_rates"] = {t: 0 for t in set(self._label_completions["completed_tasks"])}
|
|
141
|
+
for t in self._label_completions["completed_tasks"]:
|
|
142
|
+
self._label_completions["completion_rates"][t] += 1
|
|
143
|
+
self._label_completions["completion_rates"] = {
|
|
144
|
+
t: self._label_completions["completion_rates"][t] / len(self._label_completions["completed_tasks"])
|
|
145
|
+
for t in self._label_completions["completion_rates"]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
def _process_episode_completion(self, infos: Dict[str, Any], moving_avg_window: int = 500, alpha=0.9) -> None:
|
|
129
149
|
"""Process episode completion - stats, etc."""
|
|
130
150
|
self.timer.start("process_episode_stats")
|
|
131
151
|
|
|
@@ -148,6 +168,29 @@ class MettaGridEnv(MettaGridPufferBase):
|
|
|
148
168
|
for n, v in infos["agent"].items():
|
|
149
169
|
infos["agent"][n] = v / self.num_agents
|
|
150
170
|
|
|
171
|
+
# If reward estimates are set, plot them compared to the mean reward
|
|
172
|
+
if self.mg_config.game.reward_estimates:
|
|
173
|
+
infos["reward_estimates"] = {}
|
|
174
|
+
infos["reward_estimates"]["diff_from_efficient_optimal"] = (
|
|
175
|
+
self.mg_config.game.reward_estimates["most_efficient_optimal_reward"] - episode_rewards.mean()
|
|
176
|
+
)
|
|
177
|
+
infos["reward_estimates"]["diff_from_inefficient_optimal"] = (
|
|
178
|
+
self.mg_config.game.reward_estimates["least_efficient_optimal_reward"] - episode_rewards.mean()
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
self._update_label_completions(moving_avg_window)
|
|
182
|
+
|
|
183
|
+
# only plot label completions once we have a full moving average window, to prevent initial bias
|
|
184
|
+
if len(self._label_completions["completed_tasks"]) == moving_avg_window:
|
|
185
|
+
infos["label_completions"] = self._label_completions["completion_rates"]
|
|
186
|
+
|
|
187
|
+
if self.mg_config.label not in self.per_label_rewards:
|
|
188
|
+
self.per_label_rewards[self.mg_config.label] = 0
|
|
189
|
+
self.per_label_rewards[self.mg_config.label] += episode_rewards.mean()
|
|
190
|
+
infos["per_label_rewards"] = (
|
|
191
|
+
alpha * self.per_label_rewards[self.mg_config.label] + (1 - alpha) * episode_rewards.mean()
|
|
192
|
+
)
|
|
193
|
+
|
|
151
194
|
# Add attributes
|
|
152
195
|
attributes: Dict[str, Any] = {
|
|
153
196
|
"seed": self._current_seed,
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
#include "../stats_tracker.hpp"
|
|
11
11
|
#include "agent_config.hpp"
|
|
12
12
|
#include "constants.hpp"
|
|
13
|
-
#include "objects/box.hpp"
|
|
14
13
|
#include "types.hpp"
|
|
15
14
|
|
|
16
15
|
class Agent : public GridObject {
|
|
@@ -44,7 +43,6 @@ public:
|
|
|
44
43
|
GridLocation prev_location;
|
|
45
44
|
std::string prev_action_name;
|
|
46
45
|
unsigned int steps_without_motion;
|
|
47
|
-
Box* box;
|
|
48
46
|
|
|
49
47
|
Agent(GridCoord r, GridCoord c, const AgentConfig& config)
|
|
50
48
|
: group(config.group_id),
|
|
@@ -67,8 +65,7 @@ public:
|
|
|
67
65
|
reward(nullptr),
|
|
68
66
|
prev_location(r, c, GridLayer::AgentLayer),
|
|
69
67
|
prev_action_name(""),
|
|
70
|
-
steps_without_motion(0)
|
|
71
|
-
box(nullptr) {
|
|
68
|
+
steps_without_motion(0) {
|
|
72
69
|
populate_initial_inventory(config.initial_inventory);
|
|
73
70
|
GridObject::init(config.type_id, config.type_name, GridLocation(r, c, GridLayer::AgentLayer));
|
|
74
71
|
}
|
|
File without changes
|
|
@@ -34,7 +34,6 @@ from wandb.errors import CommError
|
|
|
34
34
|
# Globals #
|
|
35
35
|
# --------------------------------------------------------------------------- #
|
|
36
36
|
|
|
37
|
-
WANDB_ENTITY: str = os.getenv("WANDB_ENTITY", "metta-research")
|
|
38
37
|
GOOGLE_DRIVE_CREDENTIALS_FILE: str = os.getenv("GOOGLE_DRIVE_CREDENTIALS_FILE", "~/.config/gcloud/credentials.json")
|
|
39
38
|
GOOGLE_DRIVE_TOKEN_FILE: str = os.getenv("GOOGLE_DRIVE_TOKEN_FILE", "~/.config/gcloud/token.json")
|
|
40
39
|
|
|
@@ -256,6 +255,7 @@ def is_public_uri(url: str | None) -> bool:
|
|
|
256
255
|
class WandbURI:
|
|
257
256
|
"""Parsed representation of a W&B artifact URI."""
|
|
258
257
|
|
|
258
|
+
entity: str
|
|
259
259
|
project: str
|
|
260
260
|
artifact_path: str
|
|
261
261
|
version: str = "latest"
|
|
@@ -273,26 +273,40 @@ class WandbURI:
|
|
|
273
273
|
path_part, version = body, "latest"
|
|
274
274
|
|
|
275
275
|
if "/" not in path_part:
|
|
276
|
-
raise ValueError("Malformed W&B URI – expected wandb
|
|
276
|
+
raise ValueError("Malformed W&B URI – expected wandb://entity/project/artifact:version")
|
|
277
|
+
|
|
278
|
+
parts = path_part.split("/")
|
|
279
|
+
|
|
280
|
+
if len(parts) >= 3:
|
|
281
|
+
entity = parts[0]
|
|
282
|
+
project = parts[1]
|
|
283
|
+
artifact_path = "/".join(parts[2:])
|
|
284
|
+
elif len(parts) == 2:
|
|
285
|
+
# 2-part format: use WANDB_ENTITY if set; otherwise default to 'metta-research'
|
|
286
|
+
# Note: Do not import from metta.* here; mettagrid must remain decoupled.
|
|
287
|
+
project = parts[0]
|
|
288
|
+
artifact_path = parts[1]
|
|
289
|
+
entity = os.getenv("WANDB_ENTITY", "metta-research")
|
|
290
|
+
else:
|
|
291
|
+
raise ValueError("Malformed W&B URI – expected wandb://entity/project/artifact:version")
|
|
277
292
|
|
|
278
|
-
project
|
|
279
|
-
|
|
280
|
-
raise ValueError("Artifact path must be non-empty")
|
|
293
|
+
if not project or not artifact_path:
|
|
294
|
+
raise ValueError("Project and artifact path must be non-empty")
|
|
281
295
|
|
|
282
|
-
return cls(project, artifact_path, version)
|
|
296
|
+
return cls(entity, project, artifact_path, version)
|
|
283
297
|
|
|
284
298
|
# ---------- helpers ---------- #
|
|
285
299
|
def qname(self) -> str:
|
|
286
300
|
"""`entity/project/artifact_path:version` – accepted by `wandb.Api().artifact()`."""
|
|
287
|
-
return f"{
|
|
301
|
+
return f"{self.entity}/{self.project}/{self.artifact_path}:{self.version}"
|
|
288
302
|
|
|
289
303
|
def http_url(self) -> str:
|
|
290
304
|
"""Human-readable URL for this artifact version."""
|
|
291
|
-
return f"https://wandb.ai/{
|
|
305
|
+
return f"https://wandb.ai/{self.entity}/{self.project}/artifacts/{self.artifact_path}/{self.version}"
|
|
292
306
|
|
|
293
307
|
# pretty print
|
|
294
308
|
def __str__(self) -> str: # noqa: D401 (keep dunder)
|
|
295
|
-
return f"wandb://{self.project}/{self.artifact_path}:{self.version}"
|
|
309
|
+
return f"wandb://{self.entity}/{self.project}/{self.artifact_path}:{self.version}"
|
|
296
310
|
|
|
297
311
|
|
|
298
312
|
def upload_bytes_to_wandb(uri: WandbURI, blob: bytes, name: str) -> None:
|
|
@@ -306,7 +320,7 @@ def upload_bytes_to_wandb(uri: WandbURI, blob: bytes, name: str) -> None:
|
|
|
306
320
|
|
|
307
321
|
|
|
308
322
|
@contextmanager
|
|
309
|
-
def wandb_export_context(project: str, entity: str
|
|
323
|
+
def wandb_export_context(project: str, entity: str) -> wandb.Run:
|
|
310
324
|
"""
|
|
311
325
|
Context manager that ensures a wandb run exists for artifact exports.
|
|
312
326
|
TODO: Remove this after switching to using wandb_context
|
|
@@ -376,7 +390,7 @@ def upload_file_to_wandb(uri, local_file: str, name: str) -> None:
|
|
|
376
390
|
)
|
|
377
391
|
|
|
378
392
|
try:
|
|
379
|
-
with wandb_export_context(uri.project,
|
|
393
|
+
with wandb_export_context(uri.project, uri.entity) as run:
|
|
380
394
|
# Create and log the artifact
|
|
381
395
|
artifact = wandb.Artifact(uri.artifact_path, type="file")
|
|
382
396
|
artifact.add_file(local_file, name=name)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mettagrid
|
|
3
|
-
Version: 0.2
|
|
3
|
+
Version: 0.2.0.2
|
|
4
4
|
Summary: A fast grid-based open-ended MARL environment
|
|
5
5
|
Author-email: David Bloomin <daveey@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://daveey.github.io
|
|
8
8
|
Project-URL: Repository, https://github.com/Metta-AI/mettagrid
|
|
9
9
|
Keywords: gridworld,minigrid,rl,reinforcement-learning,environment,gym
|
|
10
|
-
Requires-Python:
|
|
10
|
+
Requires-Python: <3.12,>=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
13
|
Requires-Dist: boto3>=1.38.32
|
|
@@ -18,7 +18,7 @@ Requires-Dist: google-auth-oauthlib>=1.0.0
|
|
|
18
18
|
Requires-Dist: gymnasium==0.29.1
|
|
19
19
|
Requires-Dist: matplotlib>=3.10.3
|
|
20
20
|
Requires-Dist: numpy<2,>=1.26.4
|
|
21
|
-
Requires-Dist: omegaconf>=2.
|
|
21
|
+
Requires-Dist: omegaconf>=2.3.0
|
|
22
22
|
Requires-Dist: duckdb>=1.3.0
|
|
23
23
|
Requires-Dist: pettingzoo<1.25,>=1.24.1
|
|
24
24
|
Requires-Dist: pufferlib<3.1.0,>=3.0.0
|