continual-foragax 0.28.1__tar.gz → 0.29.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 (143) hide show
  1. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/PKG-INFO +1 -1
  2. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/pyproject.toml +2 -2
  3. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/continual_foragax.egg-info/PKG-INFO +1 -1
  4. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/env.py +51 -13
  5. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/objects.py +28 -4
  6. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/registry.py +25 -8
  7. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/tests/test_foragax.py +99 -4
  8. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/tests/test_registry.py +101 -0
  9. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/README.md +0 -0
  10. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/setup.cfg +0 -0
  11. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/continual_foragax.egg-info/SOURCES.txt +0 -0
  12. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/continual_foragax.egg-info/dependency_links.txt +0 -0
  13. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/continual_foragax.egg-info/entry_points.txt +0 -0
  14. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/continual_foragax.egg-info/requires.txt +0 -0
  15. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/continual_foragax.egg-info/top_level.txt +0 -0
  16. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/__init__.py +0 -0
  17. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/colors.py +0 -0
  18. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100897.txt +0 -0
  19. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100928.txt +0 -0
  20. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100929.txt +0 -0
  21. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100930.txt +0 -0
  22. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100931.txt +0 -0
  23. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106714.txt +0 -0
  24. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106715.txt +0 -0
  25. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106716.txt +0 -0
  26. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106717.txt +0 -0
  27. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106718.txt +0 -0
  28. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106930.txt +0 -0
  29. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106931.txt +0 -0
  30. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106932.txt +0 -0
  31. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106933.txt +0 -0
  32. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106934.txt +0 -0
  33. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106935.txt +0 -0
  34. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106936.txt +0 -0
  35. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106937.txt +0 -0
  36. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106938.txt +0 -0
  37. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106939.txt +0 -0
  38. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106940.txt +0 -0
  39. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106941.txt +0 -0
  40. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106942.txt +0 -0
  41. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106943.txt +0 -0
  42. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106994.txt +0 -0
  43. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106995.txt +0 -0
  44. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106996.txt +0 -0
  45. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106997.txt +0 -0
  46. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106998.txt +0 -0
  47. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106999.txt +0 -0
  48. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107000.txt +0 -0
  49. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107001.txt +0 -0
  50. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107002.txt +0 -0
  51. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107003.txt +0 -0
  52. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107004.txt +0 -0
  53. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107005.txt +0 -0
  54. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107006.txt +0 -0
  55. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107007.txt +0 -0
  56. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107008.txt +0 -0
  57. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107009.txt +0 -0
  58. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107010.txt +0 -0
  59. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107011.txt +0 -0
  60. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107012.txt +0 -0
  61. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107013.txt +0 -0
  62. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107014.txt +0 -0
  63. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107015.txt +0 -0
  64. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107016.txt +0 -0
  65. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107017.txt +0 -0
  66. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107018.txt +0 -0
  67. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107019.txt +0 -0
  68. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107020.txt +0 -0
  69. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107021.txt +0 -0
  70. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107022.txt +0 -0
  71. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107023.txt +0 -0
  72. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107024.txt +0 -0
  73. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107025.txt +0 -0
  74. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107026.txt +0 -0
  75. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107027.txt +0 -0
  76. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107028.txt +0 -0
  77. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107029.txt +0 -0
  78. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107030.txt +0 -0
  79. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107031.txt +0 -0
  80. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107032.txt +0 -0
  81. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107033.txt +0 -0
  82. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107034.txt +0 -0
  83. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107035.txt +0 -0
  84. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107036.txt +0 -0
  85. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107037.txt +0 -0
  86. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107038.txt +0 -0
  87. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107039.txt +0 -0
  88. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107040.txt +0 -0
  89. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107041.txt +0 -0
  90. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107042.txt +0 -0
  91. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107043.txt +0 -0
  92. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107044.txt +0 -0
  93. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107045.txt +0 -0
  94. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107046.txt +0 -0
  95. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107047.txt +0 -0
  96. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107048.txt +0 -0
  97. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107049.txt +0 -0
  98. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107050.txt +0 -0
  99. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107051.txt +0 -0
  100. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107052.txt +0 -0
  101. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107053.txt +0 -0
  102. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107054.txt +0 -0
  103. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107055.txt +0 -0
  104. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107056.txt +0 -0
  105. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107057.txt +0 -0
  106. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107058.txt +0 -0
  107. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107059.txt +0 -0
  108. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107060.txt +0 -0
  109. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107061.txt +0 -0
  110. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107062.txt +0 -0
  111. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107063.txt +0 -0
  112. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107064.txt +0 -0
  113. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107065.txt +0 -0
  114. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107066.txt +0 -0
  115. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107067.txt +0 -0
  116. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107068.txt +0 -0
  117. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107069.txt +0 -0
  118. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107070.txt +0 -0
  119. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107071.txt +0 -0
  120. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID115808.txt +0 -0
  121. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID115812.txt +0 -0
  122. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID146811.txt +0 -0
  123. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156831.txt +0 -0
  124. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156835.txt +0 -0
  125. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156839.txt +0 -0
  126. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156843.txt +0 -0
  127. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156847.txt +0 -0
  128. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156851.txt +0 -0
  129. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156855.txt +0 -0
  130. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156859.txt +0 -0
  131. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156863.txt +0 -0
  132. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156867.txt +0 -0
  133. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156871.txt +0 -0
  134. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156875.txt +0 -0
  135. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156879.txt +0 -0
  136. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156883.txt +0 -0
  137. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156887.txt +0 -0
  138. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/elements.txt +0 -0
  139. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/metadata.txt +0 -0
  140. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/data/ECA_non-blended_custom/sources.txt +0 -0
  141. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/rendering.py +0 -0
  142. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/src/foragax/weather.py +0 -0
  143. {continual_foragax-0.28.1 → continual_foragax-0.29.0}/tests/test_benchmark.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continual-foragax
3
- Version: 0.28.1
3
+ Version: 0.29.0
4
4
  Summary: A continual reinforcement learning benchmark
5
5
  Author-email: Steven Tang <stang5@ualberta.ca>
6
6
  Requires-Python: >=3.8
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "continual-foragax"
3
- version = "0.28.1"
3
+ version = "0.29.0"
4
4
  description = "A continual reinforcement learning benchmark"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -30,7 +30,7 @@ build-backend = "setuptools.build_meta"
30
30
  [tool]
31
31
  [tool.commitizen]
32
32
  name = "cz_conventional_commits"
33
- version = "0.28.1"
33
+ version = "0.29.0"
34
34
  tag_format = "$version"
35
35
  version_files = ["pyproject.toml"]
36
36
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continual-foragax
3
- Version: 0.28.1
3
+ Version: 0.29.0
4
4
  Summary: A continual reinforcement learning benchmark
5
5
  Author-email: Steven Tang <stang5@ualberta.ca>
6
6
  Requires-Python: >=3.8
@@ -61,6 +61,7 @@ class EnvState(environment.EnvState):
61
61
  object_grid: jax.Array
62
62
  biome_grid: jax.Array
63
63
  time: int
64
+ digestion_buffer: jax.Array
64
65
 
65
66
 
66
67
  class ForagaxEnv(environment.Environment):
@@ -102,11 +103,6 @@ class ForagaxEnv(environment.Environment):
102
103
  if self.nowrap and not self.full_world:
103
104
  objects = objects + (PADDING,)
104
105
  self.objects = objects
105
- self.weather_object = None
106
- for o in objects:
107
- if isinstance(o, WeatherObject):
108
- self.weather_object = o
109
- break
110
106
 
111
107
  # JIT-compatible versions of object and biome properties
112
108
  self.object_ids = jnp.arange(len(objects))
@@ -117,6 +113,13 @@ class ForagaxEnv(environment.Environment):
117
113
 
118
114
  self.reward_fns = [o.reward for o in objects]
119
115
  self.regen_delay_fns = [o.regen_delay for o in objects]
116
+ self.digestion_steps_fns = [o.digestion_steps for o in objects]
117
+
118
+ # Compute digestion steps per object (using max_digestion_steps attribute)
119
+ object_max_digestion_steps = jnp.array([o.max_digestion_steps for o in objects])
120
+ self.max_digestion_steps = (
121
+ int(jnp.max(object_max_digestion_steps)) + 1 if len(objects) > 0 else 0
122
+ )
120
123
 
121
124
  self.biome_object_frequencies = jnp.array(
122
125
  [b.object_frequencies for b in biomes]
@@ -237,12 +240,36 @@ class ForagaxEnv(environment.Environment):
237
240
 
238
241
  # 2. HANDLE COLLISIONS AND REWARDS
239
242
  obj_at_pos = current_objects[pos[1], pos[0]]
240
- key, subkey = jax.random.split(key)
241
- reward = jax.lax.switch(obj_at_pos, self.reward_fns, state.time, subkey)
242
243
  is_collectable = self.object_collectable[obj_at_pos]
244
+ should_collect = is_collectable & (obj_at_pos > 0)
245
+
246
+ # Handle digestion: add reward to buffer if collected
247
+ digestion_buffer = state.digestion_buffer
248
+ key, reward_subkey = jax.random.split(key)
249
+ object_reward = jax.lax.switch(
250
+ obj_at_pos, self.reward_fns, state.time, reward_subkey
251
+ )
252
+ key, digestion_subkey = jax.random.split(key)
253
+ digestion_steps = jax.lax.switch(
254
+ obj_at_pos, self.digestion_steps_fns, state.time, digestion_subkey
255
+ )
256
+ reward = jnp.where(should_collect & (digestion_steps == 0), object_reward, 0.0)
257
+ if self.max_digestion_steps > 0:
258
+ # Add delayed rewards to buffer
259
+ digestion_buffer = jax.lax.cond(
260
+ should_collect & (digestion_steps > 0),
261
+ lambda: digestion_buffer.at[
262
+ (state.time + digestion_steps) % self.max_digestion_steps
263
+ ].add(object_reward),
264
+ lambda: digestion_buffer,
265
+ )
266
+ # Deliver current rewards
267
+ current_index = state.time % self.max_digestion_steps
268
+ reward += digestion_buffer[current_index]
269
+ digestion_buffer = digestion_buffer.at[current_index].set(0.0)
243
270
 
244
271
  # 3. HANDLE OBJECT COLLECTION AND RESPAWNING
245
- key, subkey, rand_key = jax.random.split(key, 3)
272
+ key, regen_subkey, rand_key = jax.random.split(key, 3)
246
273
 
247
274
  # Decrement timers (stored as negative values)
248
275
  is_timer = state.object_grid < 0
@@ -252,7 +279,7 @@ class ForagaxEnv(environment.Environment):
252
279
 
253
280
  # Collect object: set a timer
254
281
  regen_delay = jax.lax.switch(
255
- obj_at_pos, self.regen_delay_fns, state.time, subkey
282
+ obj_at_pos, self.regen_delay_fns, state.time, regen_subkey
256
283
  )
257
284
  encoded_timer = obj_at_pos - ((regen_delay + 1) * num_obj_types)
258
285
 
@@ -301,10 +328,13 @@ class ForagaxEnv(environment.Environment):
301
328
  )
302
329
 
303
330
  info = {"discount": self.discount(state, params)}
304
- if self.weather_object is not None:
305
- info["temperature"] = get_temperature(
306
- self.weather_object.rewards, state.time, self.weather_object.repeat
307
- )
331
+ temperatures = jnp.zeros(len(self.objects))
332
+ for obj_index, obj in enumerate(self.objects):
333
+ if isinstance(obj, WeatherObject):
334
+ temperatures = temperatures.at[obj_index].set(
335
+ get_temperature(obj.rewards, state.time, obj.repeat)
336
+ )
337
+ info["temperatures"] = temperatures
308
338
  info["biome_id"] = state.biome_grid[pos[1], pos[0]]
309
339
  info["object_collected_id"] = jax.lax.select(should_collect, obj_at_pos, -1)
310
340
 
@@ -314,6 +344,7 @@ class ForagaxEnv(environment.Environment):
314
344
  object_grid=object_grid,
315
345
  biome_grid=state.biome_grid,
316
346
  time=state.time + 1,
347
+ digestion_buffer=digestion_buffer,
317
348
  )
318
349
 
319
350
  done = self.is_terminal(state, params)
@@ -352,6 +383,7 @@ class ForagaxEnv(environment.Environment):
352
383
  object_grid=object_grid,
353
384
  biome_grid=biome_grid,
354
385
  time=0,
386
+ digestion_buffer=jnp.zeros((self.max_digestion_steps,)),
355
387
  )
356
388
 
357
389
  return self.get_obs(state, params), state
@@ -412,6 +444,12 @@ class ForagaxEnv(environment.Environment):
412
444
  int,
413
445
  ),
414
446
  "time": spaces.Discrete(params.max_steps_in_episode),
447
+ "digestion_buffer": spaces.Box(
448
+ -jnp.inf,
449
+ jnp.inf,
450
+ (self.max_digestion_steps,),
451
+ float,
452
+ ),
415
453
  }
416
454
  )
417
455
 
@@ -1,5 +1,5 @@
1
1
  import abc
2
- from typing import Tuple
2
+ from typing import Optional, Tuple
3
3
 
4
4
  import jax
5
5
  import jax.numpy as jnp
@@ -17,12 +17,14 @@ class BaseForagaxObject:
17
17
  collectable: bool = False,
18
18
  color: Tuple[int, int, int] = (0, 0, 0),
19
19
  random_respawn: bool = False,
20
+ max_digestion_steps: int = 0,
20
21
  ):
21
22
  self.name = name
22
23
  self.blocking = blocking
23
24
  self.collectable = collectable
24
25
  self.color = color
25
26
  self.random_respawn = random_respawn
27
+ self.max_digestion_steps = max_digestion_steps
26
28
 
27
29
  @abc.abstractmethod
28
30
  def reward(self, clock: int, rng: jax.Array) -> float:
@@ -30,8 +32,8 @@ class BaseForagaxObject:
30
32
  raise NotImplementedError
31
33
 
32
34
  @abc.abstractmethod
33
- def regen_delay(self, clock: int, rng: jax.Array) -> int:
34
- """Regeneration delay function."""
35
+ def digestion_steps(self, clock: int, rng: jax.Array) -> int:
36
+ """Digestion steps function."""
35
37
  raise NotImplementedError
36
38
 
37
39
 
@@ -47,10 +49,17 @@ class DefaultForagaxObject(BaseForagaxObject):
47
49
  regen_delay: Tuple[int, int] = (10, 100),
48
50
  color: Tuple[int, int, int] = (255, 255, 255),
49
51
  random_respawn: bool = False,
52
+ digestion_steps: int = 0,
53
+ max_digestion_steps: Optional[int] = None,
50
54
  ):
51
- super().__init__(name, blocking, collectable, color, random_respawn)
55
+ if max_digestion_steps is None:
56
+ max_digestion_steps = digestion_steps
57
+ super().__init__(
58
+ name, blocking, collectable, color, random_respawn, max_digestion_steps
59
+ )
52
60
  self.reward_val = reward
53
61
  self.regen_delay_range = regen_delay
62
+ self.digestion_steps_val = digestion_steps
54
63
 
55
64
  def reward(self, clock: int, rng: jax.Array) -> float:
56
65
  """Default reward function."""
@@ -61,6 +70,10 @@ class DefaultForagaxObject(BaseForagaxObject):
61
70
  min_delay, max_delay = self.regen_delay_range
62
71
  return jax.random.randint(rng, (), min_delay, max_delay)
63
72
 
73
+ def digestion_steps(self, clock: int, rng: jax.Array) -> int:
74
+ """Default digestion steps function."""
75
+ return self.digestion_steps_val
76
+
64
77
 
65
78
  class NormalRegenForagaxObject(DefaultForagaxObject):
66
79
  """Object with regeneration delay from a normal distribution."""
@@ -74,6 +87,8 @@ class NormalRegenForagaxObject(DefaultForagaxObject):
74
87
  std_regen_delay: int = 1,
75
88
  color: Tuple[int, int, int] = (0, 0, 0),
76
89
  random_respawn: bool = False,
90
+ digestion_steps: int = 0,
91
+ max_digestion_steps: Optional[int] = None,
77
92
  ):
78
93
  super().__init__(
79
94
  name=name,
@@ -82,6 +97,8 @@ class NormalRegenForagaxObject(DefaultForagaxObject):
82
97
  regen_delay=(mean_regen_delay, mean_regen_delay),
83
98
  color=color,
84
99
  random_respawn=random_respawn,
100
+ digestion_steps=digestion_steps,
101
+ max_digestion_steps=max_digestion_steps,
85
102
  )
86
103
  self.mean_regen_delay = mean_regen_delay
87
104
  self.std_regen_delay = std_regen_delay
@@ -105,6 +122,8 @@ class WeatherObject(NormalRegenForagaxObject):
105
122
  std_regen_delay: int = 1,
106
123
  color: Tuple[int, int, int] = (0, 0, 0),
107
124
  random_respawn: bool = False,
125
+ digestion_steps: int = 0,
126
+ max_digestion_steps: Optional[int] = None,
108
127
  ):
109
128
  super().__init__(
110
129
  name=name,
@@ -113,6 +132,8 @@ class WeatherObject(NormalRegenForagaxObject):
113
132
  std_regen_delay=std_regen_delay,
114
133
  color=color,
115
134
  random_respawn=random_respawn,
135
+ digestion_steps=digestion_steps,
136
+ max_digestion_steps=max_digestion_steps,
116
137
  )
117
138
  self.rewards = rewards
118
139
  self.repeat = repeat
@@ -319,6 +340,7 @@ def create_weather_objects(
319
340
  multiplier: float = 1.0,
320
341
  same_color: bool = False,
321
342
  random_respawn: bool = False,
343
+ digestion_steps: int = 0,
322
344
  ):
323
345
  """Create HOT and COLD WeatherObject instances using the specified file.
324
346
 
@@ -348,6 +370,7 @@ def create_weather_objects(
348
370
  multiplier=multiplier,
349
371
  color=hot_color,
350
372
  random_respawn=random_respawn,
373
+ digestion_steps=digestion_steps,
351
374
  )
352
375
 
353
376
  cold_color = hot_color if same_color else (0, 255, 255)
@@ -358,6 +381,7 @@ def create_weather_objects(
358
381
  multiplier=-multiplier,
359
382
  color=cold_color,
360
383
  random_respawn=random_respawn,
384
+ digestion_steps=digestion_steps,
361
385
  )
362
386
 
363
387
  return hot, cold
@@ -83,6 +83,19 @@ ENV_CONFIGS: Dict[str, Dict[str, Any]] = {
83
83
  "nowrap": False,
84
84
  "deterministic_spawn": True,
85
85
  },
86
+ "ForagaxWeather-v6": {
87
+ "size": (15, 15),
88
+ "aperture_size": None,
89
+ "objects": None,
90
+ "biomes": (
91
+ # Hot biome
92
+ Biome(start=(0, 3), stop=(15, 5), object_frequencies=(0.5, 0.0)),
93
+ # Cold biome
94
+ Biome(start=(0, 10), stop=(15, 12), object_frequencies=(0.0, 0.5)),
95
+ ),
96
+ "nowrap": False,
97
+ "deterministic_spawn": True,
98
+ },
86
99
  "ForagaxTwoBiome-v1": {
87
100
  "size": (15, 15),
88
101
  "aperture_size": None,
@@ -348,7 +361,6 @@ def make(
348
361
  observation_type: str = "color",
349
362
  aperture_size: Optional[Tuple[int, int]] = (5, 5),
350
363
  file_index: int = 0,
351
- nowrap: Optional[bool] = None,
352
364
  **kwargs: Any,
353
365
  ) -> ForagaxEnv:
354
366
  """Create a Foragax environment.
@@ -358,9 +370,7 @@ def make(
358
370
  observation_type: The type of observation to use. One of "object", "rgb", or "color".
359
371
  aperture_size: The size of the agent's observation aperture. If -1, full world observation.
360
372
  If None, the default for the environment is used.
361
- file_index: File index for weather objects. nowrap: If True, disables
362
- wrapping around environment boundaries. If None, uses defaults per
363
- environment.
373
+ file_index: File index for weather objects.
364
374
  **kwargs: Additional keyword arguments to pass to the ForagaxEnv constructor.
365
375
 
366
376
  Returns:
@@ -376,8 +386,6 @@ def make(
376
386
  else:
377
387
  aperture_size = (aperture_size, aperture_size)
378
388
  config["aperture_size"] = aperture_size
379
- if nowrap is not None:
380
- config["nowrap"] = nowrap
381
389
 
382
390
  # Handle special size and biome configurations
383
391
  if env_id in (
@@ -459,10 +467,19 @@ def make(
459
467
  "ForagaxWeather-v3",
460
468
  "ForagaxWeather-v4",
461
469
  "ForagaxWeather-v5",
470
+ "ForagaxWeather-v6",
471
+ )
472
+ random_respawn = env_id in (
473
+ "ForagaxWeather-v4",
474
+ "ForagaxWeather-v5",
475
+ "ForagaxWeather-v6",
462
476
  )
463
- random_respawn = env_id in ("ForagaxWeather-v4", "ForagaxWeather-v5")
477
+ digestion_steps = 10 if env_id in ("ForagaxWeather-v6") else 0
464
478
  hot, cold = create_weather_objects(
465
- file_index=file_index, same_color=same_color, random_respawn=random_respawn
479
+ file_index=file_index,
480
+ same_color=same_color,
481
+ random_respawn=random_respawn,
482
+ digestion_steps=digestion_steps,
466
483
  )
467
484
  config["objects"] = (hot, cold)
468
485
 
@@ -1034,13 +1034,57 @@ def test_info_temperature():
1034
1034
  key, step_key = jax.random.split(key)
1035
1035
  _, state, _, _, info = env.step(step_key, state, Actions.UP, params)
1036
1036
 
1037
- assert "temperature" in info
1038
- # Temperature should be based on time=0, so first temperature value
1039
- assert info["temperature"] == 10.0
1037
+ assert "temperatures" in info
1038
+ # Temperatures should be an array with temperature at index 1 (object ID 1 for the weather object)
1039
+ assert len(info["temperatures"]) == 2 # EMPTY + 1 weather object
1040
+ assert info["temperatures"][0] == 0.0 # EMPTY
1041
+ assert info["temperatures"][1] == 10.0 # weather object at index 1
1040
1042
 
1041
1043
  key, step_key = jax.random.split(key)
1042
1044
  _, state, _, _, info = env.step(step_key, state, Actions.UP, params)
1043
- assert info["temperature"] == 20.0 # Next temperature value
1045
+ assert info["temperatures"][1] == 20.0 # Next temperature value
1046
+
1047
+
1048
+ def test_info_multiple_weather_objects():
1049
+ """Test that info contains temperatures for multiple weather objects."""
1050
+ key = jax.random.key(0)
1051
+ # Create two weather objects
1052
+ hot_obj = WeatherObject(
1053
+ name="hot",
1054
+ rewards=jnp.array([10.0, 20.0]),
1055
+ repeat=1,
1056
+ multiplier=1.0,
1057
+ )
1058
+ cold_obj = WeatherObject(
1059
+ name="cold",
1060
+ rewards=jnp.array([5.0, 15.0]),
1061
+ repeat=1,
1062
+ multiplier=-1.0,
1063
+ )
1064
+
1065
+ env = ForagaxEnv(
1066
+ size=(5, 5),
1067
+ objects=(hot_obj, cold_obj),
1068
+ biomes=(Biome(object_frequencies=(0.1, 0.1)),),
1069
+ observation_type="color",
1070
+ )
1071
+ params = env.default_params
1072
+ obs, state = env.reset(key, params)
1073
+
1074
+ key, step_key = jax.random.split(key)
1075
+ _, state, _, _, info = env.step(step_key, state, Actions.UP, params)
1076
+
1077
+ # Should have temperatures array
1078
+ assert "temperatures" in info
1079
+ assert len(info["temperatures"]) == 3 # EMPTY + 2 objects
1080
+ assert info["temperatures"][0] == 0.0 # EMPTY
1081
+ assert info["temperatures"][1] == 10.0 # hot object at index 1
1082
+ assert info["temperatures"][2] == 5.0 # cold object at index 2 (raw temperature)
1083
+
1084
+ key, step_key = jax.random.split(key)
1085
+ _, state, _, _, info = env.step(step_key, state, Actions.UP, params)
1086
+ assert info["temperatures"][1] == 20.0 # hot next
1087
+ assert info["temperatures"][2] == 15.0 # cold next
1044
1088
 
1045
1089
 
1046
1090
  def test_info_biome_id():
@@ -1108,3 +1152,54 @@ def test_info_object_collected_id():
1108
1152
 
1109
1153
  assert info["object_collected_id"] == -1 # No object collected
1110
1154
  assert reward == 0.0
1155
+
1156
+
1157
+ def test_digestion_delay():
1158
+ """Test that rewards are delayed by digestion_steps for objects with k > 0."""
1159
+ key = jax.random.key(0)
1160
+
1161
+ # Create an object with digestion delay of 2 steps
1162
+ delayed_flower = DefaultForagaxObject(
1163
+ name="delayed_flower",
1164
+ reward=5.0,
1165
+ collectable=True,
1166
+ color=(0, 255, 0),
1167
+ digestion_steps=2,
1168
+ )
1169
+
1170
+ env = ForagaxEnv(
1171
+ size=(7, 7),
1172
+ objects=(delayed_flower,),
1173
+ observation_type="color",
1174
+ )
1175
+ params = env.default_params
1176
+ _, state = env.reset(key, params)
1177
+
1178
+ delayed_flower_id = 1 # 0 is EMPTY
1179
+
1180
+ # Place the delayed flower and move the agent to it
1181
+ grid = jnp.zeros((7, 7), dtype=int)
1182
+ grid = grid.at[4, 3].set(delayed_flower_id)
1183
+ state = state.replace(object_grid=grid, pos=jnp.array([3, 3]))
1184
+
1185
+ # Collect the flower by moving down - should get no immediate reward
1186
+ key, step_key = jax.random.split(key)
1187
+ _, state, reward, _, info = env.step(step_key, state, Actions.DOWN, params)
1188
+
1189
+ assert info["object_collected_id"] == delayed_flower_id
1190
+ assert reward == 0.0 # No immediate reward due to digestion delay
1191
+
1192
+ # Step 1: Still no reward (time=1, reward should arrive at time=2)
1193
+ key, step_key = jax.random.split(key)
1194
+ _, state, reward, _, _ = env.step(step_key, state, Actions.UP, params)
1195
+ assert reward == 0.0
1196
+
1197
+ # Step 2: Reward should arrive now (time=2)
1198
+ key, step_key = jax.random.split(key)
1199
+ _, state, reward, _, _ = env.step(step_key, state, Actions.UP, params)
1200
+ assert reward == 5.0
1201
+
1202
+ # Step 3: No more rewards
1203
+ key, step_key = jax.random.split(key)
1204
+ _, state, reward, _, _ = env.step(step_key, state, Actions.UP, params)
1205
+ assert reward == 0.0
@@ -181,6 +181,107 @@ def test_foragax_weather_v5_color_configuration():
181
181
  assert hot_v5.color == cold_v5.color, "v5 should use same color for hot and cold"
182
182
 
183
183
 
184
+ def test_foragax_weather_v6_registry():
185
+ """Test that ForagaxWeather-v6 can be created via registry and has correct config."""
186
+ env = make("ForagaxWeather-v6", aperture_size=(5, 5))
187
+
188
+ # Check basic configuration
189
+ assert env.name == "ForagaxWeather-v6"
190
+ assert env.deterministic_spawn is True
191
+ assert env.nowrap is False # v6 enables wrapping
192
+
193
+ # Check that weather objects have random_respawn=True
194
+ hot, cold = env.objects[1], env.objects[2] # Skip EMPTY (index 0)
195
+ assert hot.name == "hot"
196
+ assert cold.name == "cold"
197
+ assert hot.random_respawn is True
198
+ assert cold.random_respawn is True
199
+
200
+ # Check digestion steps
201
+ assert hot.max_digestion_steps == 10 # digestion_steps=10
202
+ assert cold.max_digestion_steps == 10 # digestion_steps=10
203
+
204
+ # Test basic functionality
205
+ key = jax.random.key(0)
206
+ obs, state = env.reset(key, env.default_params)
207
+ assert obs.shape == (5, 5, 1) # 1 color channel (hot/cold same color, no padding)
208
+
209
+ # Test stepping
210
+ key, step_key = jax.random.split(key)
211
+ action = env.action_space(env.default_params).sample(step_key)
212
+ obs2, state2, reward, done, info = env.step(
213
+ step_key, state, action, env.default_params
214
+ )
215
+ assert obs2.shape == (5, 5, 1)
216
+ assert not done
217
+
218
+
219
+ def test_foragax_weather_v6_deterministic_spawn():
220
+ """Test that ForagaxWeather-v6 uses deterministic spawning."""
221
+ env = make("ForagaxWeather-v6", aperture_size=(5, 5))
222
+ params = env.default_params
223
+
224
+ # Test that multiple resets with same key produce same object placement
225
+ key = jax.random.key(42)
226
+ _, state1 = env.reset(key, params)
227
+
228
+ key = jax.random.key(42) # Same key
229
+ _, state2 = env.reset(key, params)
230
+
231
+ # Object grids should be identical (deterministic spawn)
232
+ chex.assert_trees_all_equal(state1.object_grid, state2.object_grid)
233
+
234
+ # But different keys should produce different placements
235
+ key1 = jax.random.key(42)
236
+ key2 = jax.random.key(43)
237
+ _, state1 = env.reset(key1, params)
238
+ _, state2 = env.reset(key2, params)
239
+
240
+ # Should be different (shuffled deterministically)
241
+ assert not jnp.array_equal(state1.object_grid, state2.object_grid)
242
+
243
+ # Test that number of objects is the same
244
+ num_hot_1 = jnp.sum(state1.object_grid == 1)
245
+ num_cold_1 = jnp.sum(state1.object_grid == 2)
246
+ num_hot_2 = jnp.sum(state2.object_grid == 1)
247
+ num_cold_2 = jnp.sum(state2.object_grid == 2)
248
+ assert num_hot_1 == num_hot_2
249
+ assert num_cold_1 == num_cold_2
250
+
251
+
252
+ def test_foragax_weather_v6_random_respawn():
253
+ """Test that ForagaxWeather-v6 weather objects have random_respawn=True."""
254
+ env = make("ForagaxWeather-v6", aperture_size=(5, 5))
255
+
256
+ # Check that weather objects have random_respawn=True
257
+ hot, cold = env.objects[1], env.objects[2] # Skip EMPTY
258
+ assert hot.random_respawn is True, "Hot objects should have random_respawn=True"
259
+ assert cold.random_respawn is True, "Cold objects should have random_respawn=True"
260
+
261
+
262
+ def test_foragax_weather_v6_color_configuration():
263
+ """Test that ForagaxWeather-v6 weather objects use the same color."""
264
+ env = make("ForagaxWeather-v6", aperture_size=(5, 5))
265
+ hot_v6, cold_v6 = env.objects[1], env.objects[2]
266
+
267
+ # Same color configuration: v6 uses same color
268
+ assert hot_v6.color == cold_v6.color, "v6 should use same color for hot and cold"
269
+
270
+
271
+ def test_foragax_weather_v6_digestion_steps():
272
+ """Test that ForagaxWeather-v6 weather objects have digestion_steps=10."""
273
+ env = make("ForagaxWeather-v6", aperture_size=(5, 5))
274
+
275
+ # Check that weather objects have digestion_steps=10
276
+ hot, cold = env.objects[1], env.objects[2] # Skip EMPTY
277
+ assert hot.digestion_steps(0, jax.random.key(0)) == 10, (
278
+ "Hot objects should have digestion_steps=10"
279
+ )
280
+ assert cold.digestion_steps(0, jax.random.key(0)) == 10, (
281
+ "Cold objects should have digestion_steps=10"
282
+ )
283
+
284
+
184
285
  def test_foragax_twobiome_v10_registry():
185
286
  """Test that ForagaxTwoBiome-v10 can be created via registry and has correct config."""
186
287
  env = make("ForagaxTwoBiome-v10", aperture_size=(5, 5))