comrad-bench 1.0.0__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.
Files changed (391) hide show
  1. comrad_bench-1.0.0/LICENSE +21 -0
  2. comrad_bench-1.0.0/MANIFEST.in +5 -0
  3. comrad_bench-1.0.0/PKG-INFO +229 -0
  4. comrad_bench-1.0.0/README.md +161 -0
  5. comrad_bench-1.0.0/comrad/curriculum/__init__.py +30 -0
  6. comrad_bench-1.0.0/comrad/curriculum/base.py +133 -0
  7. comrad_bench-1.0.0/comrad/curriculum/learning_progress.py +136 -0
  8. comrad_bench-1.0.0/comrad/curriculum/observer.py +100 -0
  9. comrad_bench-1.0.0/comrad/curriculum/omni.py +74 -0
  10. comrad_bench-1.0.0/comrad/curriculum/plr.py +208 -0
  11. comrad_bench-1.0.0/comrad/curriculum/sequential.py +72 -0
  12. comrad_bench-1.0.0/comrad/curriculum/uniform.py +20 -0
  13. comrad_bench-1.0.0/comrad/enjoy.py +22 -0
  14. comrad_bench-1.0.0/comrad/envs/__init__.py +0 -0
  15. comrad_bench-1.0.0/comrad/envs/action_space.py +513 -0
  16. comrad_bench-1.0.0/comrad/envs/doom_gym.py +766 -0
  17. comrad_bench-1.0.0/comrad/envs/doom_params.py +252 -0
  18. comrad_bench-1.0.0/comrad/envs/multi_wad_env.py +171 -0
  19. comrad_bench-1.0.0/comrad/envs/multiagent/__init__.py +0 -0
  20. comrad_bench-1.0.0/comrad/envs/multiagent/doom_multiagent.py +224 -0
  21. comrad_bench-1.0.0/comrad/envs/multiagent/doom_multiagent_wrapper.py +592 -0
  22. comrad_bench-1.0.0/comrad/envs/wad_catalog.py +46 -0
  23. comrad_bench-1.0.0/comrad/examples/WandB_Scraper/plot_wandb.py +230 -0
  24. comrad_bench-1.0.0/comrad/examples/agent_run_env.py +50 -0
  25. comrad_bench-1.0.0/comrad/examples/inspect_obs.py +28 -0
  26. comrad_bench-1.0.0/comrad/examples/single_player.py +21 -0
  27. comrad_bench-1.0.0/comrad/examples/vizdoom.pyi +3233 -0
  28. comrad_bench-1.0.0/comrad/examples/you_run_env.py +192 -0
  29. comrad_bench-1.0.0/comrad/misc/resource_greed.py +90 -0
  30. comrad_bench-1.0.0/comrad/models/__init__.py +0 -0
  31. comrad_bench-1.0.0/comrad/models/doom_model.py +47 -0
  32. comrad_bench-1.0.0/comrad/models/happo_model.py +376 -0
  33. comrad_bench-1.0.0/comrad/models/mappo_model.py +85 -0
  34. comrad_bench-1.0.0/comrad/models/qmix_model.py +415 -0
  35. comrad_bench-1.0.0/comrad/models/qplex_mixer.py +443 -0
  36. comrad_bench-1.0.0/comrad/record_topdown_heatmap.py +1299 -0
  37. comrad_bench-1.0.0/comrad/record_video.py +262 -0
  38. comrad_bench-1.0.0/comrad/scenarios/ammo_carrier.cfg +39 -0
  39. comrad_bench-1.0.0/comrad/scenarios/ammo_carrier.wad +0 -0
  40. comrad_bench-1.0.0/comrad/scenarios/armory_siege.cfg +41 -0
  41. comrad_bench-1.0.0/comrad/scenarios/armory_siege.wad +0 -0
  42. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_0.wad +0 -0
  43. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_1.wad +0 -0
  44. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_10.wad +0 -0
  45. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_11.wad +0 -0
  46. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_12.wad +0 -0
  47. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_13.wad +0 -0
  48. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_14.wad +0 -0
  49. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_15.wad +0 -0
  50. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_16.wad +0 -0
  51. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_17.wad +0 -0
  52. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_18.wad +0 -0
  53. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_19.wad +0 -0
  54. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_2.wad +0 -0
  55. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_20.wad +0 -0
  56. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_21.wad +0 -0
  57. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_22.wad +0 -0
  58. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_23.wad +0 -0
  59. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_3.wad +0 -0
  60. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_4.wad +0 -0
  61. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_5.wad +0 -0
  62. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_6.wad +0 -0
  63. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_7.wad +0 -0
  64. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_8.wad +0 -0
  65. comrad_bench-1.0.0/comrad/scenarios/batch_armory/armory_9.wad +0 -0
  66. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_0.wad +0 -0
  67. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_1.wad +0 -0
  68. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_10.wad +0 -0
  69. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_11.wad +0 -0
  70. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_12.wad +0 -0
  71. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_13.wad +0 -0
  72. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_14.wad +0 -0
  73. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_15.wad +0 -0
  74. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_16.wad +0 -0
  75. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_17.wad +0 -0
  76. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_18.wad +0 -0
  77. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_19.wad +0 -0
  78. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_2.wad +0 -0
  79. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_20.wad +0 -0
  80. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_21.wad +0 -0
  81. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_22.wad +0 -0
  82. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_23.wad +0 -0
  83. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_24.wad +0 -0
  84. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_25.wad +0 -0
  85. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_26.wad +0 -0
  86. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_27.wad +0 -0
  87. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_28.wad +0 -0
  88. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_29.wad +0 -0
  89. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_3.wad +0 -0
  90. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_30.wad +0 -0
  91. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_31.wad +0 -0
  92. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_32.wad +0 -0
  93. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_33.wad +0 -0
  94. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_34.wad +0 -0
  95. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_35.wad +0 -0
  96. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_36.wad +0 -0
  97. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_37.wad +0 -0
  98. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_38.wad +0 -0
  99. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_39.wad +0 -0
  100. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_4.wad +0 -0
  101. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_40.wad +0 -0
  102. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_41.wad +0 -0
  103. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_42.wad +0 -0
  104. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_43.wad +0 -0
  105. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_44.wad +0 -0
  106. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_45.wad +0 -0
  107. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_46.wad +0 -0
  108. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_47.wad +0 -0
  109. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_48.wad +0 -0
  110. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_49.wad +0 -0
  111. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_5.wad +0 -0
  112. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_50.wad +0 -0
  113. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_51.wad +0 -0
  114. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_52.wad +0 -0
  115. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_53.wad +0 -0
  116. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_54.wad +0 -0
  117. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_55.wad +0 -0
  118. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_56.wad +0 -0
  119. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_57.wad +0 -0
  120. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_58.wad +0 -0
  121. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_59.wad +0 -0
  122. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_6.wad +0 -0
  123. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_60.wad +0 -0
  124. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_61.wad +0 -0
  125. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_62.wad +0 -0
  126. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_63.wad +0 -0
  127. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_64.wad +0 -0
  128. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_65.wad +0 -0
  129. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_7.wad +0 -0
  130. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_8.wad +0 -0
  131. comrad_bench-1.0.0/comrad/scenarios/batch_lava_maze/lava_maze_9.wad +0 -0
  132. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_bridge_intro.wad +0 -0
  133. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_bridge_mastery.wad +0 -0
  134. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_bridge_progress.wad +0 -0
  135. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_easy_intro.wad +0 -0
  136. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_easy_mastery.wad +0 -0
  137. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_easy_movers.wad +0 -0
  138. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_easy_spacing.wad +0 -0
  139. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_hard_default.wad +0 -0
  140. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_hard_endgame.wad +0 -0
  141. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_hard_extended.wad +0 -0
  142. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_hard_intro.wad +0 -0
  143. comrad_bench-1.0.0/comrad/scenarios/batch_platform_chain_curriculum/platform_chain_hard_tighter.wad +0 -0
  144. comrad_bench-1.0.0/comrad/scenarios/coop_health_gathering.cfg +31 -0
  145. comrad_bench-1.0.0/comrad/scenarios/coop_health_gathering.wad +0 -0
  146. comrad_bench-1.0.0/comrad/scenarios/coop_puzzle.cfg +39 -0
  147. comrad_bench-1.0.0/comrad/scenarios/coop_puzzle.wad +0 -0
  148. comrad_bench-1.0.0/comrad/scenarios/dumb_enemies.cfg +35 -0
  149. comrad_bench-1.0.0/comrad/scenarios/dumb_enemies.wad +0 -0
  150. comrad_bench-1.0.0/comrad/scenarios/foraging_commons.cfg +36 -0
  151. comrad_bench-1.0.0/comrad/scenarios/foraging_commons.wad +0 -0
  152. comrad_bench-1.0.0/comrad/scenarios/lava_maze.cfg +41 -0
  153. comrad_bench-1.0.0/comrad/scenarios/lava_maze.wad +0 -0
  154. comrad_bench-1.0.0/comrad/scenarios/lava_maze_simple.cfg +32 -0
  155. comrad_bench-1.0.0/comrad/scenarios/lava_maze_simple.wad +0 -0
  156. comrad_bench-1.0.0/comrad/scenarios/lavapit.cfg +46 -0
  157. comrad_bench-1.0.0/comrad/scenarios/lavapit.wad +0 -0
  158. comrad_bench-1.0.0/comrad/scenarios/platform_chain.cfg +38 -0
  159. comrad_bench-1.0.0/comrad/scenarios/platform_chain.wad +0 -0
  160. comrad_bench-1.0.0/comrad/scenarios/platform_chain_easy.cfg +38 -0
  161. comrad_bench-1.0.0/comrad/scenarios/platform_chain_easy.wad +0 -0
  162. comrad_bench-1.0.0/comrad/scenarios/rhythm_sync.cfg +49 -0
  163. comrad_bench-1.0.0/comrad/scenarios/rhythm_sync.wad +0 -0
  164. comrad_bench-1.0.0/comrad/scenarios/smart_enemies.cfg +36 -0
  165. comrad_bench-1.0.0/comrad/scenarios/smart_enemies.wad +0 -0
  166. comrad_bench-1.0.0/comrad/scenarios/stag_hunt_arena.cfg +39 -0
  167. comrad_bench-1.0.0/comrad/scenarios/stag_hunt_arena.wad +0 -0
  168. comrad_bench-1.0.0/comrad/scenarios/stealth_labyrinth.cfg +45 -0
  169. comrad_bench-1.0.0/comrad/scenarios/stealth_labyrinth.wad +0 -0
  170. comrad_bench-1.0.0/comrad/templates/asdf.sh +24 -0
  171. comrad_bench-1.0.0/comrad/templates/run.sh +364 -0
  172. comrad_bench-1.0.0/comrad/templates/run_algo.sh +84 -0
  173. comrad_bench-1.0.0/comrad/templates/run_bench.sh +77 -0
  174. comrad_bench-1.0.0/comrad/tests/__init__.py +0 -0
  175. comrad_bench-1.0.0/comrad/tests/test_doom_utils_additional_input.py +60 -0
  176. comrad_bench-1.0.0/comrad/tests/test_lava_maze_action_mask.py +86 -0
  177. comrad_bench-1.0.0/comrad/tests/test_record_topdown_heatmap.py +271 -0
  178. comrad_bench-1.0.0/comrad/tests/test_train_all.py +118 -0
  179. comrad_bench-1.0.0/comrad/tests/test_train_all_scaling.py +168 -0
  180. comrad_bench-1.0.0/comrad/train.py +228 -0
  181. comrad_bench-1.0.0/comrad/train_all.py +368 -0
  182. comrad_bench-1.0.0/comrad/utils/__init__.py +0 -0
  183. comrad_bench-1.0.0/comrad/utils/doom_render.py +35 -0
  184. comrad_bench-1.0.0/comrad/utils/doom_utils.py +644 -0
  185. comrad_bench-1.0.0/comrad/utils/recording_actions.py +29 -0
  186. comrad_bench-1.0.0/comrad/utils/video_uploader.py +51 -0
  187. comrad_bench-1.0.0/comrad/utils/wad_utils.py +55 -0
  188. comrad_bench-1.0.0/comrad/wrappers/__init__.py +0 -0
  189. comrad_bench-1.0.0/comrad/wrappers/action_mask.py +73 -0
  190. comrad_bench-1.0.0/comrad/wrappers/additional_input.py +101 -0
  191. comrad_bench-1.0.0/comrad/wrappers/agent_id_wrapper.py +42 -0
  192. comrad_bench-1.0.0/comrad/wrappers/exploration.py +56 -0
  193. comrad_bench-1.0.0/comrad/wrappers/multiplayer_stats.py +61 -0
  194. comrad_bench-1.0.0/comrad/wrappers/observation_space.py +75 -0
  195. comrad_bench-1.0.0/comrad/wrappers/reward_shaping.py +262 -0
  196. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/__init__.py +18 -0
  197. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/ammo_carrier.py +231 -0
  198. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/armory_siege.py +264 -0
  199. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/coop_health_gathering.py +124 -0
  200. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/coop_puzzle.py +131 -0
  201. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/dumb_enemies.py +135 -0
  202. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/foraging_commons.py +147 -0
  203. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/gathering_reward_shaping.py +44 -0
  204. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/lava_maze.py +303 -0
  205. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/lava_maze_simple.py +300 -0
  206. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/lavapit_reward_shaping.py +235 -0
  207. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/mwh_reward_shaping.py +79 -0
  208. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/pitfall_reward_shaping.py +93 -0
  209. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/platform_chain.py +115 -0
  210. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/rhythm_sync.py +111 -0
  211. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/rhythm_sync_dense.py +327 -0
  212. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/smart_enemies.py +132 -0
  213. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/stag_hunt_arena.py +128 -0
  214. comrad_bench-1.0.0/comrad/wrappers/scenario_wrappers/stealth_labyrinth.py +157 -0
  215. comrad_bench-1.0.0/comrad/wrappers/shared_reward.py +55 -0
  216. comrad_bench-1.0.0/comrad/wrappers/step_human_input.py +37 -0
  217. comrad_bench-1.0.0/comrad/wrappers/video_recorder.py +347 -0
  218. comrad_bench-1.0.0/comrad_bench.egg-info/PKG-INFO +229 -0
  219. comrad_bench-1.0.0/comrad_bench.egg-info/SOURCES.txt +389 -0
  220. comrad_bench-1.0.0/comrad_bench.egg-info/dependency_links.txt +1 -0
  221. comrad_bench-1.0.0/comrad_bench.egg-info/requires.txt +49 -0
  222. comrad_bench-1.0.0/comrad_bench.egg-info/top_level.txt +2 -0
  223. comrad_bench-1.0.0/pyproject.toml +107 -0
  224. comrad_bench-1.0.0/sample_factory/__init__.py +9 -0
  225. comrad_bench-1.0.0/sample_factory/algo/__init__.py +0 -0
  226. comrad_bench-1.0.0/sample_factory/algo/evaluators/__init__.py +0 -0
  227. comrad_bench-1.0.0/sample_factory/algo/evaluators/default_evaluator.py +0 -0
  228. comrad_bench-1.0.0/sample_factory/algo/learning/__init__.py +0 -0
  229. comrad_bench-1.0.0/sample_factory/algo/learning/batcher.py +271 -0
  230. comrad_bench-1.0.0/sample_factory/algo/learning/learner.py +1322 -0
  231. comrad_bench-1.0.0/sample_factory/algo/learning/learner_dqn.py +450 -0
  232. comrad_bench-1.0.0/sample_factory/algo/learning/learner_happo.py +818 -0
  233. comrad_bench-1.0.0/sample_factory/algo/learning/learner_qmix.py +1254 -0
  234. comrad_bench-1.0.0/sample_factory/algo/learning/learner_worker.py +178 -0
  235. comrad_bench-1.0.0/sample_factory/algo/learning/rnn_utils.py +158 -0
  236. comrad_bench-1.0.0/sample_factory/algo/runners/__init__.py +0 -0
  237. comrad_bench-1.0.0/sample_factory/algo/runners/runner.py +774 -0
  238. comrad_bench-1.0.0/sample_factory/algo/runners/runner_parallel.py +65 -0
  239. comrad_bench-1.0.0/sample_factory/algo/runners/runner_serial.py +27 -0
  240. comrad_bench-1.0.0/sample_factory/algo/sampling/__init__.py +0 -0
  241. comrad_bench-1.0.0/sample_factory/algo/sampling/batched_sampling.py +466 -0
  242. comrad_bench-1.0.0/sample_factory/algo/sampling/evaluation_sampling_api.py +315 -0
  243. comrad_bench-1.0.0/sample_factory/algo/sampling/inference_worker.py +524 -0
  244. comrad_bench-1.0.0/sample_factory/algo/sampling/non_batched_sampling.py +709 -0
  245. comrad_bench-1.0.0/sample_factory/algo/sampling/rollout_worker.py +308 -0
  246. comrad_bench-1.0.0/sample_factory/algo/sampling/sampler.py +296 -0
  247. comrad_bench-1.0.0/sample_factory/algo/sampling/sampling_utils.py +70 -0
  248. comrad_bench-1.0.0/sample_factory/algo/sampling/stats.py +31 -0
  249. comrad_bench-1.0.0/sample_factory/algo/sampling/sync_sampling_api.py +65 -0
  250. comrad_bench-1.0.0/sample_factory/algo/utils/__init__.py +0 -0
  251. comrad_bench-1.0.0/sample_factory/algo/utils/action_distributions.py +350 -0
  252. comrad_bench-1.0.0/sample_factory/algo/utils/agent_policy_mapping.py +62 -0
  253. comrad_bench-1.0.0/sample_factory/algo/utils/context.py +50 -0
  254. comrad_bench-1.0.0/sample_factory/algo/utils/env_info.py +151 -0
  255. comrad_bench-1.0.0/sample_factory/algo/utils/epsilon_schedule.py +50 -0
  256. comrad_bench-1.0.0/sample_factory/algo/utils/gymnasium_utils.py +128 -0
  257. comrad_bench-1.0.0/sample_factory/algo/utils/heartbeat.py +35 -0
  258. comrad_bench-1.0.0/sample_factory/algo/utils/joint_replay_buffer.py +296 -0
  259. comrad_bench-1.0.0/sample_factory/algo/utils/joint_sequence_replay_buffer.py +225 -0
  260. comrad_bench-1.0.0/sample_factory/algo/utils/make_env.py +388 -0
  261. comrad_bench-1.0.0/sample_factory/algo/utils/misc.py +44 -0
  262. comrad_bench-1.0.0/sample_factory/algo/utils/model_sharing.py +170 -0
  263. comrad_bench-1.0.0/sample_factory/algo/utils/multiprocessing_utils.py +41 -0
  264. comrad_bench-1.0.0/sample_factory/algo/utils/optimizers.py +189 -0
  265. comrad_bench-1.0.0/sample_factory/algo/utils/replay_buffer.py +390 -0
  266. comrad_bench-1.0.0/sample_factory/algo/utils/rl_utils.py +117 -0
  267. comrad_bench-1.0.0/sample_factory/algo/utils/running_mean_std.py +152 -0
  268. comrad_bench-1.0.0/sample_factory/algo/utils/shared_buffers.py +248 -0
  269. comrad_bench-1.0.0/sample_factory/algo/utils/spaces/__init__.py +0 -0
  270. comrad_bench-1.0.0/sample_factory/algo/utils/spaces/discretized.py +14 -0
  271. comrad_bench-1.0.0/sample_factory/algo/utils/tensor_dict.py +156 -0
  272. comrad_bench-1.0.0/sample_factory/algo/utils/tensor_utils.py +47 -0
  273. comrad_bench-1.0.0/sample_factory/algo/utils/torch_utils.py +66 -0
  274. comrad_bench-1.0.0/sample_factory/cfg/__init__.py +0 -0
  275. comrad_bench-1.0.0/sample_factory/cfg/arguments.py +617 -0
  276. comrad_bench-1.0.0/sample_factory/cfg/cfg.py +1187 -0
  277. comrad_bench-1.0.0/sample_factory/cfg/configurable.py +6 -0
  278. comrad_bench-1.0.0/sample_factory/enjoy.py +292 -0
  279. comrad_bench-1.0.0/sample_factory/envs/__init__.py +0 -0
  280. comrad_bench-1.0.0/sample_factory/envs/create_env.py +46 -0
  281. comrad_bench-1.0.0/sample_factory/envs/env_utils.py +142 -0
  282. comrad_bench-1.0.0/sample_factory/envs/env_wrappers.py +457 -0
  283. comrad_bench-1.0.0/sample_factory/envs/pettingzoo_envs.py +79 -0
  284. comrad_bench-1.0.0/sample_factory/eval.py +119 -0
  285. comrad_bench-1.0.0/sample_factory/export_onnx.py +202 -0
  286. comrad_bench-1.0.0/sample_factory/huggingface/__init__.py +0 -0
  287. comrad_bench-1.0.0/sample_factory/huggingface/huggingface_utils.py +154 -0
  288. comrad_bench-1.0.0/sample_factory/huggingface/load_from_hub.py +27 -0
  289. comrad_bench-1.0.0/sample_factory/huggingface/push_to_hub.py +61 -0
  290. comrad_bench-1.0.0/sample_factory/launcher/__init__.py +0 -0
  291. comrad_bench-1.0.0/sample_factory/launcher/launcher_utils.py +6 -0
  292. comrad_bench-1.0.0/sample_factory/launcher/run.py +77 -0
  293. comrad_bench-1.0.0/sample_factory/launcher/run_description.py +194 -0
  294. comrad_bench-1.0.0/sample_factory/launcher/run_ngc.py +72 -0
  295. comrad_bench-1.0.0/sample_factory/launcher/run_processes.py +142 -0
  296. comrad_bench-1.0.0/sample_factory/launcher/run_slurm.py +173 -0
  297. comrad_bench-1.0.0/sample_factory/model/__init__.py +0 -0
  298. comrad_bench-1.0.0/sample_factory/model/action_parameterization.py +76 -0
  299. comrad_bench-1.0.0/sample_factory/model/actor_critic.py +351 -0
  300. comrad_bench-1.0.0/sample_factory/model/core.py +86 -0
  301. comrad_bench-1.0.0/sample_factory/model/decoder.py +35 -0
  302. comrad_bench-1.0.0/sample_factory/model/encoder.py +242 -0
  303. comrad_bench-1.0.0/sample_factory/model/model_factory.py +60 -0
  304. comrad_bench-1.0.0/sample_factory/model/model_utils.py +93 -0
  305. comrad_bench-1.0.0/sample_factory/model/utils.py +17 -0
  306. comrad_bench-1.0.0/sample_factory/pbt/__init__.py +0 -0
  307. comrad_bench-1.0.0/sample_factory/pbt/population_based_training.py +415 -0
  308. comrad_bench-1.0.0/sample_factory/tests/__init__.py +0 -0
  309. comrad_bench-1.0.0/sample_factory/tests/algo/__init__.py +0 -0
  310. comrad_bench-1.0.0/sample_factory/tests/algo/happo/__init__.py +0 -0
  311. comrad_bench-1.0.0/sample_factory/tests/algo/happo/conftest.py +111 -0
  312. comrad_bench-1.0.0/sample_factory/tests/algo/happo/test_critic_rnn.py +347 -0
  313. comrad_bench-1.0.0/sample_factory/tests/algo/happo/test_critic_rnn_training.py +420 -0
  314. comrad_bench-1.0.0/sample_factory/tests/algo/happo/test_helpers.py +112 -0
  315. comrad_bench-1.0.0/sample_factory/tests/algo/happo/test_learner.py +328 -0
  316. comrad_bench-1.0.0/sample_factory/tests/algo/happo/test_loss.py +384 -0
  317. comrad_bench-1.0.0/sample_factory/tests/algo/happo/test_model.py +280 -0
  318. comrad_bench-1.0.0/sample_factory/tests/algo/mappo/__init__.py +0 -0
  319. comrad_bench-1.0.0/sample_factory/tests/algo/mappo/conftest.py +56 -0
  320. comrad_bench-1.0.0/sample_factory/tests/algo/mappo/test_critic.py +176 -0
  321. comrad_bench-1.0.0/sample_factory/tests/algo/mappo/test_model.py +138 -0
  322. comrad_bench-1.0.0/sample_factory/tests/algo/mappo/test_rnn_edges.py +171 -0
  323. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/__init__.py +0 -0
  324. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/conftest.py +179 -0
  325. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_buffer.py +332 -0
  326. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_forward_equivalence.py +399 -0
  327. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_learner.py +458 -0
  328. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_qplex_compound_actions.py +512 -0
  329. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_rnn_buffer.py +189 -0
  330. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_rnn_core.py +390 -0
  331. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_rnn_loss.py +365 -0
  332. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_rnn_model.py +545 -0
  333. comrad_bench-1.0.0/sample_factory/tests/algo/qmix/test_transitions.py +277 -0
  334. comrad_bench-1.0.0/sample_factory/tests/algo/qplex/test_qatten_regress.py +31 -0
  335. comrad_bench-1.0.0/sample_factory/tests/algo/qplex/test_qplex.py +893 -0
  336. comrad_bench-1.0.0/sample_factory/tests/algo/qplex/test_qplex_cfg_validation.py +56 -0
  337. comrad_bench-1.0.0/sample_factory/tests/algo/qplex/test_qplex_compound_convergence.py +487 -0
  338. comrad_bench-1.0.0/sample_factory/tests/algo/test_action_distributions.py +259 -0
  339. comrad_bench-1.0.0/sample_factory/tests/algo/test_joint_replay_buffer_rng.py +83 -0
  340. comrad_bench-1.0.0/sample_factory/tests/algo/test_learner.py +172 -0
  341. comrad_bench-1.0.0/sample_factory/tests/algo/test_model.py +64 -0
  342. comrad_bench-1.0.0/sample_factory/tests/algo/test_model_builder.py +60 -0
  343. comrad_bench-1.0.0/sample_factory/tests/algo/test_pbt.py +25 -0
  344. comrad_bench-1.0.0/sample_factory/tests/algo/test_rms.py +68 -0
  345. comrad_bench-1.0.0/sample_factory/tests/algo/test_rnn.py +64 -0
  346. comrad_bench-1.0.0/sample_factory/tests/algo/test_spaces.py +21 -0
  347. comrad_bench-1.0.0/sample_factory/tests/algo/test_tensordict.py +67 -0
  348. comrad_bench-1.0.0/sample_factory/tests/envs/__init__.py +0 -0
  349. comrad_bench-1.0.0/sample_factory/tests/envs/test_batched_sampling_true_objective.py +81 -0
  350. comrad_bench-1.0.0/sample_factory/tests/envs/test_doom_gym_terminal_info.py +56 -0
  351. comrad_bench-1.0.0/sample_factory/tests/envs/test_doom_multiagent_wrapper.py +259 -0
  352. comrad_bench-1.0.0/sample_factory/tests/envs/tuple_action_envs/__init__.py +0 -0
  353. comrad_bench-1.0.0/sample_factory/tests/envs/tuple_action_envs/test_mixed_dist_env_batched.py +137 -0
  354. comrad_bench-1.0.0/sample_factory/tests/envs/tuple_action_envs/test_mixed_dist_env_non_batched.py +101 -0
  355. comrad_bench-1.0.0/sample_factory/tests/envs/tuple_action_envs/test_two_discrete_action_dist_env_batched.py +144 -0
  356. comrad_bench-1.0.0/sample_factory/tests/envs/tuple_action_envs/test_two_discrete_action_dist_env_non_batched.py +113 -0
  357. comrad_bench-1.0.0/sample_factory/tests/envs/utils.py +63 -0
  358. comrad_bench-1.0.0/sample_factory/tests/envs/vizdoom/__init__.py +0 -0
  359. comrad_bench-1.0.0/sample_factory/tests/envs/vizdoom/test_vizdoom_basic.py +84 -0
  360. comrad_bench-1.0.0/sample_factory/tests/envs/vizdoom/test_vizdoom_multiplayer.py +85 -0
  361. comrad_bench-1.0.0/sample_factory/tests/examples/__init__.py +0 -0
  362. comrad_bench-1.0.0/sample_factory/tests/examples/test_example.py +178 -0
  363. comrad_bench-1.0.0/sample_factory/tests/examples/test_example_multi.py +64 -0
  364. comrad_bench-1.0.0/sample_factory/tests/examples/test_example_sampler.py +31 -0
  365. comrad_bench-1.0.0/sample_factory/tests/export_onnx_utils.py +68 -0
  366. comrad_bench-1.0.0/sample_factory/tests/test_comrad_curriculum.py +595 -0
  367. comrad_bench-1.0.0/sample_factory/tests/test_comrad_train_resume.py +155 -0
  368. comrad_bench-1.0.0/sample_factory/tests/test_launcher.py +189 -0
  369. comrad_bench-1.0.0/sample_factory/tests/test_precheck.py +26 -0
  370. comrad_bench-1.0.0/sample_factory/tests/test_utils.py +60 -0
  371. comrad_bench-1.0.0/sample_factory/tests/test_video_recorder.py +444 -0
  372. comrad_bench-1.0.0/sample_factory/tests/test_video_uploader.py +107 -0
  373. comrad_bench-1.0.0/sample_factory/tests/utils.py +14 -0
  374. comrad_bench-1.0.0/sample_factory/train.py +41 -0
  375. comrad_bench-1.0.0/sample_factory/utils/__init__.py +0 -0
  376. comrad_bench-1.0.0/sample_factory/utils/algo_version.py +3 -0
  377. comrad_bench-1.0.0/sample_factory/utils/attr_dict.py +8 -0
  378. comrad_bench-1.0.0/sample_factory/utils/decay.py +47 -0
  379. comrad_bench-1.0.0/sample_factory/utils/dicts.py +103 -0
  380. comrad_bench-1.0.0/sample_factory/utils/get_available_gpus.py +42 -0
  381. comrad_bench-1.0.0/sample_factory/utils/gifs.py +41 -0
  382. comrad_bench-1.0.0/sample_factory/utils/gpu_utils.py +90 -0
  383. comrad_bench-1.0.0/sample_factory/utils/network.py +15 -0
  384. comrad_bench-1.0.0/sample_factory/utils/normalize.py +76 -0
  385. comrad_bench-1.0.0/sample_factory/utils/tb.py +91 -0
  386. comrad_bench-1.0.0/sample_factory/utils/timing.py +161 -0
  387. comrad_bench-1.0.0/sample_factory/utils/typing.py +31 -0
  388. comrad_bench-1.0.0/sample_factory/utils/utils.py +497 -0
  389. comrad_bench-1.0.0/sample_factory/utils/wandb_utils.py +76 -0
  390. comrad_bench-1.0.0/setup.cfg +4 -0
  391. comrad_bench-1.0.0/setup.py +3 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include README.md
2
+ recursive-include comrad/scenarios *.cfg *.wad
3
+ recursive-include comrad/docs *.md
4
+ recursive-include comrad/experiments *.md
5
+ recursive-include comrad/templates *.sh
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: comrad-bench
3
+ Version: 1.0.0
4
+ Summary: MARL benchmark suite in ViZDoom
5
+ Author-email: "Khoi H.B. Nguyen" <baokhoi136@gmail.com>, Tristan Tomilin <tristan.tomilin@hotmail.com>, Dimitar Zhekov <mitko.zh@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/TTomilin/COMRAD
8
+ Project-URL: Repository, https://github.com/TTomilin/COMRAD
9
+ Keywords: marl,vizdoom,reinforcement-learning,multi-agent,benchmark
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Classifier: Topic :: Games/Entertainment :: First Person Shooters
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: numpy<2.0,>=1.26.4
22
+ Requires-Dist: gymnasium[classic-control]<1.0,>=0.27
23
+ Requires-Dist: pettingzoo<1.25.0
24
+ Requires-Dist: opencv-python>=4.11.0
25
+ Requires-Dist: pygame>=2.6.1
26
+ Requires-Dist: pre-commit>=4.5.1
27
+ Requires-Dist: pynput>=1.8.1
28
+ Requires-Dist: wandb[media]==0.22.1
29
+ Requires-Dist: torch>=2.10.0
30
+ Requires-Dist: torchrl>=0.11.0
31
+ Requires-Dist: torchvision>=0.25.0
32
+ Requires-Dist: torchaudio>=2.10.0
33
+ Requires-Dist: psutil>=7.2.2
34
+ Requires-Dist: pyglet>=2.1.12
35
+ Requires-Dist: tensorboard>=2.20.0
36
+ Requires-Dist: tensorboardx>=2.6.4
37
+ Requires-Dist: threadpoolctl>=3.6.0
38
+ Requires-Dist: colorlog>=6.10.1
39
+ Requires-Dist: signal-slot-mp<2.0,>=1.0.3
40
+ Requires-Dist: filelock>=3.20.3
41
+ Requires-Dist: huggingface-hub>=0.10.0
42
+ Requires-Dist: pandas>=2.3.3
43
+ Requires-Dist: onnx>=1.19.0
44
+ Requires-Dist: onnxruntime>=1.23.2
45
+ Requires-Dist: matplotlib>=3.10.8
46
+ Requires-Dist: seaborn>=0.13.2
47
+ Requires-Dist: scipy>=1.17.0
48
+ Requires-Dist: vizdoom>=1.3.0
49
+ Provides-Extra: sample-factory
50
+ Requires-Dist: torch>=2.9.0; extra == "sample-factory"
51
+ Requires-Dist: wandb>=0.22.1; extra == "sample-factory"
52
+ Requires-Dist: tensorboard>=2.20.0; extra == "sample-factory"
53
+ Requires-Dist: colorlog>=6.10.1; extra == "sample-factory"
54
+ Requires-Dist: signal-slot-mp>=1.0.5; extra == "sample-factory"
55
+ Requires-Dist: faster-fifo>=1.5.2; extra == "sample-factory"
56
+ Requires-Dist: filelock>=3.19.1; extra == "sample-factory"
57
+ Requires-Dist: psutil>=7.1.0; extra == "sample-factory"
58
+ Requires-Dist: huggingface_hub>=0.36.0; extra == "sample-factory"
59
+ Requires-Dist: scipy>=1.16.3; extra == "sample-factory"
60
+ Provides-Extra: visual
61
+ Requires-Dist: omgifol>=0.5.1; extra == "visual"
62
+ Requires-Dist: pillow>=11.3.0; extra == "visual"
63
+ Requires-Dist: pypng>=0.20220715.0; extra == "visual"
64
+ Requires-Dist: shapely>=2.1.2; extra == "visual"
65
+ Provides-Extra: doomgen
66
+ Requires-Dist: doomgen; extra == "doomgen"
67
+ Dynamic: license-file
68
+
69
+ # COMRAD
70
+
71
+ COMRAD is a cooperative multi-agent reinforcement learning benchmark built on ViZDoom for first-person visual coordination. This repository contains the benchmark runtime assets, COMRAD-specific environment and model code, a modified Sample Factory training stack, paper artifacts, and the scripts used to produce figures, tables, and diagnostic media.
72
+
73
+ <p align="center">
74
+ <img src="results/demo_all_checkpoints/comrad_vid_gif_540.gif" alt="COMRAD demo" style="width: 100%; max-width: 960px;">
75
+ </p>
76
+
77
+ ## Repository map
78
+
79
+ | Path | Purpose |
80
+ | --- | --- |
81
+ | `comrad/` | Benchmark package: training entrypoints, environment registration, wrappers, models, shipped scenario assets, launchers, tests. |
82
+ | `sample_factory/` | Modified training engine used by COMRAD. |
83
+ | `scripts/` | Figure-generation, result aggregation, WAD rendering, and experiment helper scripts. |
84
+ | `results/` | Committed figures, tables, result summaries, and selected media artifacts. |
85
+ | `DoomGen/` | Procedural generator used to build and vary scenario WADs. |
86
+
87
+ Directory-level guides are provided in:
88
+
89
+ - [`comrad/README.md`](comrad/README.md)
90
+ - [`sample_factory/README.md`](sample_factory/README.md)
91
+ - [`scripts/README.md`](scripts/README.md)
92
+ - [`results/README.md`](results/README.md)
93
+
94
+ ## Setup
95
+
96
+ COMRAD is packaged through `pyproject.toml` and is intended to be run with `uv`.
97
+
98
+ ```bash
99
+ uv sync --all-extras
100
+ uv run pre-commit install
101
+ ```
102
+
103
+ The project requires Python 3.10 or newer. The package metadata and CI workflow are the authoritative sources for dependency resolution.
104
+
105
+ ## Single-run training
106
+
107
+ The main training entrypoint is `comrad.train`.
108
+
109
+ ```bash
110
+ uv run python -m comrad.train \
111
+ --env=stag_hunt_arena \
112
+ --algo=IPPO \
113
+ --train_for_env_steps=10000 \
114
+ --num_workers=4 \
115
+ --num_envs_per_worker=4 \
116
+ --device=cpu
117
+ ```
118
+
119
+ Training outputs are written under `train_dir/<experiment>/`. The main runtime log is:
120
+
121
+ ```bash
122
+ tail -n 120 train_dir/<experiment>/sf_log.txt
123
+ ```
124
+
125
+ For launcher-owned benchmark sweeps, use `comrad/train_all.py` instead of manually reproducing those long commands.
126
+
127
+ ## Recording and evaluation
128
+
129
+ High-resolution checkpoint recording:
130
+
131
+ ```bash
132
+ uv run python -m comrad.record_video \
133
+ --env=stag_hunt_arena \
134
+ --train_dir=train_dir \
135
+ --experiment=<experiment_name> \
136
+ --load_checkpoint_kind=best \
137
+ --resolution=1280x720
138
+ ```
139
+
140
+ Automap/top-down heatmap rendering:
141
+
142
+ ```bash
143
+ uv run python -m comrad.record_topdown_heatmap \
144
+ --env=ammo_carrier \
145
+ --train_dir=<train_root> \
146
+ --experiment=<experiment_name> \
147
+ --output_dir=results/videos/ammo_carrier_navigation_heatmap \
148
+ --device=cpu \
149
+ --overwrite
150
+ ```
151
+
152
+ Both commands expect a full experiment directory with at least `config.json` and the corresponding checkpoint directory.
153
+
154
+ ## Benchmark launchers
155
+
156
+ COMRAD ships several paper-facing launcher profiles through `comrad/train_all.py`.
157
+
158
+ - `benchmark`: full benchmark suite
159
+ - `agent_scaling`: Armory Siege agent-count sweep
160
+ - `platform_chain_curriculum`: curriculum comparison on Platform Chain
161
+ - `qmix_lr_sensitivity_pilot`: Short sensitivity study
162
+ - `qmix_lr_sensitivity_full`: Full sensitivity study
163
+
164
+ Run a launcher profile locally with:
165
+
166
+ ```bash
167
+ COMRAD_TRAIN_ALL_PROFILE=benchmark \
168
+ uv run python -m sample_factory.launcher.run \
169
+ --run=comrad.train_all \
170
+ --backend=processes \
171
+ --max_parallel=1 \
172
+ --pause_between=1
173
+ ```
174
+
175
+ The exact benchmark definitions, algorithms, root directory names, and profile constants live at the top of [`comrad/train_all.py`](comrad/train_all.py).
176
+
177
+ ## Scenario assets and DoomGen
178
+
179
+ Runtime scenario assets are stored in [`comrad/scenarios/`](comrad/scenarios/README.md) as `.cfg` and `.wad` pairs, plus pre-generated batch directories such as `batch_platform_chain_curriculum/`.
180
+
181
+ Generation workflows are in `DoomGen/`. The usual split is:
182
+
183
+ - `DoomGen/examples/benchmark`: procedural generators and geometry logic
184
+ - `comrad/scenarios/`: runtime WADs and configs consumed by training and evaluation
185
+
186
+ If a scenario generator changes, rebuild the corresponding WAD in `DoomGen/` and copy the regenerated artifact back into `comrad/scenarios/` before training or evaluation.
187
+
188
+ ### Using DoomGen as a Python library
189
+
190
+ DoomGen is declared as an optional dependency in the uv workspace. It is **not** installed by a plain `uv sync`:
191
+
192
+ ```bash
193
+ uv sync --extra doomgen # install doomgen + its deps
194
+ # or
195
+ uv run --extra doomgen python -m comrad.train ... # one-off with doomgen available
196
+ # or
197
+ uv pip install -e DoomGen/ # editable install directly from local checkout
198
+ ```
199
+
200
+ After any of these, `import doomgen` works from the root Python environment. Without `--extra doomgen`, the core COMRAD package remains self-contained and DoomGen is not pulled in.
201
+
202
+ ## Tests
203
+
204
+ Run COMRAD and Sample Factory tests with `uv`:
205
+
206
+ ```bash
207
+ uv run pytest comrad/tests -v
208
+ uv run pytest sample_factory/tests -v
209
+ ```
210
+
211
+ Tests in `comrad/tests/` focus on benchmark logic, launchers, and recorder behavior. Tests in `sample_factory/tests/` cover the modified training stack.
212
+
213
+ ## Outputs and artifacts
214
+
215
+ - `train_dir/`: experiment directories, configs, checkpoints, logs
216
+ - `results/`: committed figures, tables, result summaries, selected media
217
+ - `wandb/`: local W&B run state and uploads
218
+
219
+ See [`results/README.md`](results/README.md) for the structure of the committed artifacts.
220
+
221
+ ## License and upstream assets
222
+
223
+ The repository is released under the MIT license in [`LICENSE`](LICENSE). Upstream and third-party assets are documented in the repository itself, including the bundled `scripts/wad2image/` tool and the paper's citations to ViZDoom, Sample Factory, HARL, PyMARL, and QPLEX.
224
+
225
+ ## Acknowledgements
226
+
227
+ We would like to thank all researchers, engineers, advisors involved in this work; and the TU/e Supercomputing Center for providing the infrastructure to run the experiments. The environments are built on top of [ViZDoom](https://github.com/Farama-Foundation/ViZDoom). Our infrastructure is built on top of [Sample Factory](https://github.com/alex-petrenko/sample-factory). Our experiments were managed using [Weights & Biases](https://wandb.ai/). For on-policy actor-critic methods, we implement IPPO and MAPPO from the original implementation in [Sample Factory](https://github.com/alex-petrenko/sample-factory), and HAPPO following the [HARL codebase](https://github.com/PKU-MARL/HARL). For off-policy value decomposition methods, we implement IDQN, VDN, QMIX following the [PyMARL framework](https://github.com/oxwhirl/pymarl), and QPLEX following [official QPLEX reference implementation](https://github.com/wjh720/QPLEX).
228
+
229
+ <!-- ## Citation -->
@@ -0,0 +1,161 @@
1
+ # COMRAD
2
+
3
+ COMRAD is a cooperative multi-agent reinforcement learning benchmark built on ViZDoom for first-person visual coordination. This repository contains the benchmark runtime assets, COMRAD-specific environment and model code, a modified Sample Factory training stack, paper artifacts, and the scripts used to produce figures, tables, and diagnostic media.
4
+
5
+ <p align="center">
6
+ <img src="results/demo_all_checkpoints/comrad_vid_gif_540.gif" alt="COMRAD demo" style="width: 100%; max-width: 960px;">
7
+ </p>
8
+
9
+ ## Repository map
10
+
11
+ | Path | Purpose |
12
+ | --- | --- |
13
+ | `comrad/` | Benchmark package: training entrypoints, environment registration, wrappers, models, shipped scenario assets, launchers, tests. |
14
+ | `sample_factory/` | Modified training engine used by COMRAD. |
15
+ | `scripts/` | Figure-generation, result aggregation, WAD rendering, and experiment helper scripts. |
16
+ | `results/` | Committed figures, tables, result summaries, and selected media artifacts. |
17
+ | `DoomGen/` | Procedural generator used to build and vary scenario WADs. |
18
+
19
+ Directory-level guides are provided in:
20
+
21
+ - [`comrad/README.md`](comrad/README.md)
22
+ - [`sample_factory/README.md`](sample_factory/README.md)
23
+ - [`scripts/README.md`](scripts/README.md)
24
+ - [`results/README.md`](results/README.md)
25
+
26
+ ## Setup
27
+
28
+ COMRAD is packaged through `pyproject.toml` and is intended to be run with `uv`.
29
+
30
+ ```bash
31
+ uv sync --all-extras
32
+ uv run pre-commit install
33
+ ```
34
+
35
+ The project requires Python 3.10 or newer. The package metadata and CI workflow are the authoritative sources for dependency resolution.
36
+
37
+ ## Single-run training
38
+
39
+ The main training entrypoint is `comrad.train`.
40
+
41
+ ```bash
42
+ uv run python -m comrad.train \
43
+ --env=stag_hunt_arena \
44
+ --algo=IPPO \
45
+ --train_for_env_steps=10000 \
46
+ --num_workers=4 \
47
+ --num_envs_per_worker=4 \
48
+ --device=cpu
49
+ ```
50
+
51
+ Training outputs are written under `train_dir/<experiment>/`. The main runtime log is:
52
+
53
+ ```bash
54
+ tail -n 120 train_dir/<experiment>/sf_log.txt
55
+ ```
56
+
57
+ For launcher-owned benchmark sweeps, use `comrad/train_all.py` instead of manually reproducing those long commands.
58
+
59
+ ## Recording and evaluation
60
+
61
+ High-resolution checkpoint recording:
62
+
63
+ ```bash
64
+ uv run python -m comrad.record_video \
65
+ --env=stag_hunt_arena \
66
+ --train_dir=train_dir \
67
+ --experiment=<experiment_name> \
68
+ --load_checkpoint_kind=best \
69
+ --resolution=1280x720
70
+ ```
71
+
72
+ Automap/top-down heatmap rendering:
73
+
74
+ ```bash
75
+ uv run python -m comrad.record_topdown_heatmap \
76
+ --env=ammo_carrier \
77
+ --train_dir=<train_root> \
78
+ --experiment=<experiment_name> \
79
+ --output_dir=results/videos/ammo_carrier_navigation_heatmap \
80
+ --device=cpu \
81
+ --overwrite
82
+ ```
83
+
84
+ Both commands expect a full experiment directory with at least `config.json` and the corresponding checkpoint directory.
85
+
86
+ ## Benchmark launchers
87
+
88
+ COMRAD ships several paper-facing launcher profiles through `comrad/train_all.py`.
89
+
90
+ - `benchmark`: full benchmark suite
91
+ - `agent_scaling`: Armory Siege agent-count sweep
92
+ - `platform_chain_curriculum`: curriculum comparison on Platform Chain
93
+ - `qmix_lr_sensitivity_pilot`: Short sensitivity study
94
+ - `qmix_lr_sensitivity_full`: Full sensitivity study
95
+
96
+ Run a launcher profile locally with:
97
+
98
+ ```bash
99
+ COMRAD_TRAIN_ALL_PROFILE=benchmark \
100
+ uv run python -m sample_factory.launcher.run \
101
+ --run=comrad.train_all \
102
+ --backend=processes \
103
+ --max_parallel=1 \
104
+ --pause_between=1
105
+ ```
106
+
107
+ The exact benchmark definitions, algorithms, root directory names, and profile constants live at the top of [`comrad/train_all.py`](comrad/train_all.py).
108
+
109
+ ## Scenario assets and DoomGen
110
+
111
+ Runtime scenario assets are stored in [`comrad/scenarios/`](comrad/scenarios/README.md) as `.cfg` and `.wad` pairs, plus pre-generated batch directories such as `batch_platform_chain_curriculum/`.
112
+
113
+ Generation workflows are in `DoomGen/`. The usual split is:
114
+
115
+ - `DoomGen/examples/benchmark`: procedural generators and geometry logic
116
+ - `comrad/scenarios/`: runtime WADs and configs consumed by training and evaluation
117
+
118
+ If a scenario generator changes, rebuild the corresponding WAD in `DoomGen/` and copy the regenerated artifact back into `comrad/scenarios/` before training or evaluation.
119
+
120
+ ### Using DoomGen as a Python library
121
+
122
+ DoomGen is declared as an optional dependency in the uv workspace. It is **not** installed by a plain `uv sync`:
123
+
124
+ ```bash
125
+ uv sync --extra doomgen # install doomgen + its deps
126
+ # or
127
+ uv run --extra doomgen python -m comrad.train ... # one-off with doomgen available
128
+ # or
129
+ uv pip install -e DoomGen/ # editable install directly from local checkout
130
+ ```
131
+
132
+ After any of these, `import doomgen` works from the root Python environment. Without `--extra doomgen`, the core COMRAD package remains self-contained and DoomGen is not pulled in.
133
+
134
+ ## Tests
135
+
136
+ Run COMRAD and Sample Factory tests with `uv`:
137
+
138
+ ```bash
139
+ uv run pytest comrad/tests -v
140
+ uv run pytest sample_factory/tests -v
141
+ ```
142
+
143
+ Tests in `comrad/tests/` focus on benchmark logic, launchers, and recorder behavior. Tests in `sample_factory/tests/` cover the modified training stack.
144
+
145
+ ## Outputs and artifacts
146
+
147
+ - `train_dir/`: experiment directories, configs, checkpoints, logs
148
+ - `results/`: committed figures, tables, result summaries, selected media
149
+ - `wandb/`: local W&B run state and uploads
150
+
151
+ See [`results/README.md`](results/README.md) for the structure of the committed artifacts.
152
+
153
+ ## License and upstream assets
154
+
155
+ The repository is released under the MIT license in [`LICENSE`](LICENSE). Upstream and third-party assets are documented in the repository itself, including the bundled `scripts/wad2image/` tool and the paper's citations to ViZDoom, Sample Factory, HARL, PyMARL, and QPLEX.
156
+
157
+ ## Acknowledgements
158
+
159
+ We would like to thank all researchers, engineers, advisors involved in this work; and the TU/e Supercomputing Center for providing the infrastructure to run the experiments. The environments are built on top of [ViZDoom](https://github.com/Farama-Foundation/ViZDoom). Our infrastructure is built on top of [Sample Factory](https://github.com/alex-petrenko/sample-factory). Our experiments were managed using [Weights & Biases](https://wandb.ai/). For on-policy actor-critic methods, we implement IPPO and MAPPO from the original implementation in [Sample Factory](https://github.com/alex-petrenko/sample-factory), and HAPPO following the [HARL codebase](https://github.com/PKU-MARL/HARL). For off-policy value decomposition methods, we implement IDQN, VDN, QMIX following the [PyMARL framework](https://github.com/oxwhirl/pymarl), and QPLEX following [official QPLEX reference implementation](https://github.com/wjh720/QPLEX).
160
+
161
+ <!-- ## Citation -->
@@ -0,0 +1,30 @@
1
+ from comrad.curriculum.base import Curriculum
2
+ from comrad.curriculum.uniform import UniformCurriculum
3
+ from comrad.curriculum.sequential import SequentialCurriculum
4
+ from comrad.curriculum.learning_progress import LearningProgress
5
+ from comrad.curriculum.omni import OMNICurriculum
6
+ from comrad.curriculum.plr import PrioritizedLevelReplay
7
+
8
+ def make_curriculum(n_tasks: int, strategy: str = "uniform", **kwargs) -> Curriculum:
9
+ """Factory to spin up proper curriculum based on configuration."""
10
+ strategies = {
11
+ "uniform": UniformCurriculum,
12
+ "sequential": SequentialCurriculum,
13
+ "learning_progress": LearningProgress,
14
+ "omni": OMNICurriculum,
15
+ "plr": PrioritizedLevelReplay,
16
+ }
17
+
18
+ assert strategy in strategies, f"Unknown strategy '{strategy}'. Available: {list(strategies.keys())}"
19
+
20
+ return strategies[strategy](n_tasks=n_tasks, **kwargs)
21
+
22
+ __all__ = [
23
+ "Curriculum",
24
+ "UniformCurriculum",
25
+ "SequentialCurriculum",
26
+ "LearningProgress",
27
+ "OMNICurriculum",
28
+ "PrioritizedLevelReplay",
29
+ "make_curriculum"
30
+ ]
@@ -0,0 +1,133 @@
1
+ import multiprocessing
2
+ import os
3
+ from typing import Optional
4
+ import numpy as np
5
+
6
+
7
+ class Curriculum:
8
+ """
9
+ Abstract base curriculum class for a fixed discrete batch of tasks (WADs).
10
+ Requires multiprocessing arrays and locks for disjoint worker/learner access.
11
+ """
12
+
13
+ EMA_ALPHA = 0.1
14
+ SCORE_MEAN_VALUE_L1 = "mean_value_l1"
15
+ SCORE_MAX_VALUE_L1 = "max_value_l1"
16
+ SCORE_MEAN_ADVANTAGE = "mean_advantage"
17
+ SCORE_MAX_ADVANTAGE = "max_advantage"
18
+ SCORE_MEAN_ENTROPY = "mean_entropy"
19
+ SCORE_MAX_ENTROPY = "max_entropy"
20
+
21
+ def __init__(self, n_tasks: int, seed: Optional[int] = None, tasks: Optional[list] = None, **kwargs):
22
+ self.ctx = multiprocessing.get_context("spawn")
23
+ self._n = n_tasks
24
+ self._base_seed = int(seed) if seed is not None else int.from_bytes(os.urandom(8), "little")
25
+ self._rng_counter = self.ctx.Value("Q", 0)
26
+ self._task_ids = tuple(tasks) if tasks is not None else None
27
+
28
+ self._weights = self.ctx.Array('d', [1.0 / n_tasks] * n_tasks)
29
+ self._counts = self.ctx.Array('l', [0] * n_tasks)
30
+ self._lock = self.ctx.Lock()
31
+
32
+ def update(self, task_idx: int, episode_return: float) -> None:
33
+ """Called at end of each episode."""
34
+ with self._lock:
35
+ self._counts[task_idx] += 1
36
+ self._update_logic(task_idx, float(episode_return))
37
+ self._recompute_weights()
38
+
39
+ def update_task_score(self, task_idx: int, score: dict, num_steps: int = 1) -> None:
40
+ """Used by sample factory learners (e.g. PLR)"""
41
+ pass
42
+
43
+ def sample(self) -> int:
44
+ with self._lock:
45
+ task_idx = self._sample_logic()
46
+ return task_idx
47
+
48
+ def _sample_logic(self) -> int:
49
+ """Isolated locked core for actually rolling the random sample"""
50
+ weights = np.array(self._weights[:])
51
+ return self._choice(self._n, p=weights)
52
+
53
+ def _next_rng(self) -> np.random.Generator:
54
+ """
55
+ Generate randomness from a single shared draw counter so spawned workers
56
+ do not each replay an identical local RNG stream.
57
+ """
58
+ counter = self._rng_counter.value
59
+ self._rng_counter.value = counter + 1
60
+ seed = (self._base_seed + 0x9E3779B97F4A7C15 * counter) & ((1 << 64) - 1)
61
+ return np.random.default_rng(seed)
62
+
63
+ def _choice(self, n: int, p=None) -> int:
64
+ return int(self._next_rng().choice(n, p=p))
65
+
66
+ def _random(self) -> float:
67
+ return float(self._next_rng().random())
68
+
69
+ def _update_logic(self, task_idx: int, episode_return: float) -> None:
70
+ """Sub-classes override this to implement update behavior."""
71
+ pass
72
+
73
+ def _recompute_weights(self) -> None:
74
+ """Sub-classes override this to update probabilities inside self._weights."""
75
+ pass
76
+
77
+ def task_weights(self) -> np.ndarray:
78
+ with self._lock:
79
+ return np.array(self._weights[:])
80
+
81
+ def task_returns(self) -> np.ndarray:
82
+ """Return fast moving average or appropriate returns proxy."""
83
+ # By default just returns zeroes, overridden in LP/OMNI classes
84
+ return np.zeros(self._n)
85
+
86
+ def task_scores(self) -> np.ndarray:
87
+ """PLR scores or similar metric."""
88
+ return np.zeros(self._n)
89
+
90
+ def metrics(self) -> dict:
91
+ """General metrics reporting."""
92
+ return {}
93
+
94
+ def state_dict(self) -> dict:
95
+ with self._lock:
96
+ state = {
97
+ "version": 1,
98
+ "curriculum_type": type(self).__name__,
99
+ "n_tasks": self._n,
100
+ "base_seed": int(self._base_seed),
101
+ "rng_counter": int(self._rng_counter.value),
102
+ "weights": list(self._weights[:]),
103
+ "counts": list(self._counts[:]),
104
+ }
105
+ if self._task_ids is not None:
106
+ state["task_ids"] = list(self._task_ids)
107
+ state.update(self._state_dict_locked())
108
+ return state
109
+
110
+ def load_state_dict(self, state: dict) -> None:
111
+ expected_type = type(self).__name__
112
+ actual_type = state.get("curriculum_type", expected_type)
113
+ if actual_type != expected_type:
114
+ raise ValueError(f"Expected curriculum state for {expected_type}, got {actual_type}")
115
+ if int(state.get("n_tasks", self._n)) != self._n:
116
+ raise ValueError(f"Expected curriculum state for {self._n} tasks, got {state.get('n_tasks')}")
117
+ expected_task_ids = list(self._task_ids) if self._task_ids is not None else None
118
+ actual_task_ids = state.get("task_ids", None)
119
+ if expected_task_ids is not None and actual_task_ids != expected_task_ids:
120
+ raise ValueError(f"Expected curriculum task ids {expected_task_ids}, got {actual_task_ids}")
121
+
122
+ with self._lock:
123
+ self._base_seed = int(state.get("base_seed", self._base_seed))
124
+ self._rng_counter.value = int(state.get("rng_counter", 0))
125
+ self._weights[:] = [float(weight) for weight in state.get("weights", self._weights[:])]
126
+ self._counts[:] = [int(count) for count in state.get("counts", self._counts[:])]
127
+ self._load_state_dict_locked(state)
128
+
129
+ def _state_dict_locked(self) -> dict:
130
+ return {}
131
+
132
+ def _load_state_dict_locked(self, state: dict) -> None:
133
+ pass