cogames 0.3.64__py3-none-any.whl → 0.3.68__py3-none-any.whl

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 (141) hide show
  1. cogames/cli/client.py +0 -3
  2. cogames/cli/docsync/docsync.py +7 -1
  3. cogames/cli/mission.py +68 -53
  4. cogames/cli/policy.py +26 -10
  5. cogames/cli/submit.py +128 -142
  6. cogames/cli/utils.py +5 -0
  7. cogames/cogs_vs_clips/clip_difficulty.py +57 -0
  8. cogames/cogs_vs_clips/clips.py +103 -0
  9. cogames/cogs_vs_clips/cog.py +29 -11
  10. cogames/cogs_vs_clips/cogsguard_curriculum.py +122 -0
  11. cogames/cogs_vs_clips/cogsguard_tutorial.py +15 -16
  12. cogames/cogs_vs_clips/config.py +38 -0
  13. cogames/cogs_vs_clips/{cogs_vs_clips_mapgen.md → docs/cogs_vs_clips_mapgen.md} +8 -10
  14. cogames/cogs_vs_clips/evals/README.md +11 -35
  15. cogames/cogs_vs_clips/evals/cogsguard_evals.py +21 -6
  16. cogames/cogs_vs_clips/evals/diagnostic_evals.py +13 -101
  17. cogames/cogs_vs_clips/evals/difficulty_variants.py +16 -28
  18. cogames/cogs_vs_clips/evals/integrated_evals.py +8 -60
  19. cogames/cogs_vs_clips/evals/spanning_evals.py +48 -54
  20. cogames/cogs_vs_clips/mission.py +93 -277
  21. cogames/cogs_vs_clips/missions.py +17 -27
  22. cogames/cogs_vs_clips/{cogsguard_reward_variants.py → reward_variants.py} +22 -2
  23. cogames/cogs_vs_clips/sites.py +41 -30
  24. cogames/cogs_vs_clips/stations.py +39 -84
  25. cogames/cogs_vs_clips/team.py +46 -0
  26. cogames/cogs_vs_clips/{procedural.py → terrain.py} +14 -8
  27. cogames/cogs_vs_clips/variants.py +201 -107
  28. cogames/cogs_vs_clips/weather.py +52 -0
  29. cogames/core.py +87 -0
  30. cogames/docs/SCRIPTED_AGENT.md +3 -3
  31. cogames/evaluate.py +4 -2
  32. cogames/main.py +357 -51
  33. cogames/maps/canidate1_1000.map +1 -1
  34. cogames/maps/canidate1_1000_stations.map +2 -2
  35. cogames/maps/canidate1_500.map +1 -1
  36. cogames/maps/canidate1_500_stations.map +2 -2
  37. cogames/maps/canidate2_1000.map +1 -1
  38. cogames/maps/canidate2_1000_stations.map +2 -2
  39. cogames/maps/canidate2_500.map +1 -1
  40. cogames/maps/canidate2_500_stations.map +1 -1
  41. cogames/maps/canidate3_1000.map +1 -1
  42. cogames/maps/canidate3_1000_stations.map +2 -2
  43. cogames/maps/canidate3_500.map +1 -1
  44. cogames/maps/canidate3_500_stations.map +2 -2
  45. cogames/maps/canidate4_500.map +1 -1
  46. cogames/maps/canidate4_500_stations.map +2 -2
  47. cogames/maps/cave_base_50.map +2 -2
  48. cogames/maps/diagnostic_evals/diagnostic_agile.map +2 -2
  49. cogames/maps/diagnostic_evals/diagnostic_agile_hard.map +2 -2
  50. cogames/maps/diagnostic_evals/diagnostic_charge_up.map +6 -6
  51. cogames/maps/diagnostic_evals/diagnostic_charge_up_hard.map +6 -6
  52. cogames/maps/diagnostic_evals/diagnostic_chest_navigation1.map +6 -6
  53. cogames/maps/diagnostic_evals/diagnostic_chest_navigation1_hard.map +6 -6
  54. cogames/maps/diagnostic_evals/diagnostic_chest_navigation2.map +6 -6
  55. cogames/maps/diagnostic_evals/diagnostic_chest_navigation2_hard.map +6 -6
  56. cogames/maps/diagnostic_evals/diagnostic_chest_navigation3.map +6 -6
  57. cogames/maps/diagnostic_evals/diagnostic_chest_navigation3_hard.map +6 -6
  58. cogames/maps/diagnostic_evals/diagnostic_chest_near.map +6 -6
  59. cogames/maps/diagnostic_evals/diagnostic_chest_search.map +6 -6
  60. cogames/maps/diagnostic_evals/diagnostic_chest_search_hard.map +6 -6
  61. cogames/maps/diagnostic_evals/diagnostic_extract_lab.map +6 -6
  62. cogames/maps/diagnostic_evals/diagnostic_extract_lab_hard.map +6 -6
  63. cogames/maps/diagnostic_evals/diagnostic_memory.map +6 -6
  64. cogames/maps/diagnostic_evals/diagnostic_memory_hard.map +6 -6
  65. cogames/maps/diagnostic_evals/diagnostic_radial.map +2 -2
  66. cogames/maps/diagnostic_evals/diagnostic_radial_hard.map +2 -2
  67. cogames/maps/diagnostic_evals/diagnostic_resource_lab.map +6 -6
  68. cogames/maps/diagnostic_evals/diagnostic_unclip.map +6 -6
  69. cogames/maps/evals/eval_balanced_spread.map +6 -6
  70. cogames/maps/evals/eval_clip_oxygen.map +6 -6
  71. cogames/maps/evals/eval_collect_resources.map +6 -6
  72. cogames/maps/evals/eval_collect_resources_hard.map +6 -6
  73. cogames/maps/evals/eval_collect_resources_medium.map +6 -6
  74. cogames/maps/evals/eval_divide_and_conquer.map +6 -6
  75. cogames/maps/evals/eval_energy_starved.map +6 -6
  76. cogames/maps/evals/eval_multi_coordinated_collect_hard.map +6 -6
  77. cogames/maps/evals/eval_oxygen_bottleneck.map +6 -6
  78. cogames/maps/evals/eval_single_use_world.map +6 -6
  79. cogames/maps/evals/extractor_hub_100x100.map +6 -6
  80. cogames/maps/evals/extractor_hub_30x30.map +6 -6
  81. cogames/maps/evals/extractor_hub_50x50.map +6 -6
  82. cogames/maps/evals/extractor_hub_70x70.map +6 -6
  83. cogames/maps/evals/extractor_hub_80x80.map +6 -6
  84. cogames/maps/machina_100_stations.map +2 -2
  85. cogames/maps/machina_200_stations.map +2 -2
  86. cogames/maps/machina_200_stations_small.map +2 -2
  87. cogames/maps/machina_eval_exp01.map +2 -2
  88. cogames/maps/machina_eval_template_large.map +2 -2
  89. cogames/maps/machinatrainer4agents.map +2 -2
  90. cogames/maps/machinatrainer4agentsbase.map +2 -2
  91. cogames/maps/machinatrainerbig.map +2 -2
  92. cogames/maps/machinatrainersmall.map +2 -2
  93. cogames/maps/planky_evals/aligner_avoid_aoe.map +6 -6
  94. cogames/maps/planky_evals/aligner_full_cycle.map +6 -6
  95. cogames/maps/planky_evals/aligner_gear.map +6 -6
  96. cogames/maps/planky_evals/aligner_hearts.map +6 -6
  97. cogames/maps/planky_evals/aligner_junction.map +6 -6
  98. cogames/maps/planky_evals/exploration_distant.map +6 -6
  99. cogames/maps/planky_evals/maze.map +6 -6
  100. cogames/maps/planky_evals/miner_best_resource.map +6 -6
  101. cogames/maps/planky_evals/miner_deposit.map +6 -6
  102. cogames/maps/planky_evals/miner_extract.map +6 -6
  103. cogames/maps/planky_evals/miner_full_cycle.map +6 -6
  104. cogames/maps/planky_evals/miner_gear.map +6 -6
  105. cogames/maps/planky_evals/multi_role.map +6 -6
  106. cogames/maps/planky_evals/resource_chain.map +6 -6
  107. cogames/maps/planky_evals/scout_explore.map +6 -6
  108. cogames/maps/planky_evals/scout_gear.map +6 -6
  109. cogames/maps/planky_evals/scrambler_full_cycle.map +6 -6
  110. cogames/maps/planky_evals/scrambler_gear.map +6 -6
  111. cogames/maps/planky_evals/scrambler_target.map +6 -6
  112. cogames/maps/planky_evals/stuck_corridor.map +6 -6
  113. cogames/maps/planky_evals/survive_retreat.map +6 -6
  114. cogames/maps/training_facility_clipped.map +2 -2
  115. cogames/maps/training_facility_open_1.map +2 -2
  116. cogames/maps/training_facility_open_2.map +2 -2
  117. cogames/maps/training_facility_open_3.map +2 -2
  118. cogames/maps/training_facility_tight_4.map +2 -2
  119. cogames/maps/training_facility_tight_5.map +2 -2
  120. cogames/maps/vanilla_large.map +2 -2
  121. cogames/maps/vanilla_small.map +2 -2
  122. cogames/pickup.py +6 -5
  123. cogames/play.py +14 -16
  124. cogames/policy/nim_agents/__init__.py +0 -2
  125. cogames/policy/nim_agents/agents.py +0 -11
  126. cogames/policy/starter_agent.py +4 -1
  127. cogames/verbose.py +2 -2
  128. {cogames-0.3.64.dist-info → cogames-0.3.68.dist-info}/METADATA +45 -29
  129. cogames-0.3.68.dist-info/RECORD +160 -0
  130. metta_alo/scoring.py +7 -7
  131. cogames/cogs_vs_clips/mission_utils.py +0 -19
  132. cogames/cogs_vs_clips/tutorial_missions.py +0 -25
  133. cogames-0.3.64.dist-info/RECORD +0 -159
  134. metta_alo/job_specs.py +0 -17
  135. metta_alo/policy.py +0 -16
  136. metta_alo/pure_single_episode_runner.py +0 -75
  137. metta_alo/rollout.py +0 -322
  138. {cogames-0.3.64.dist-info → cogames-0.3.68.dist-info}/WHEEL +0 -0
  139. {cogames-0.3.64.dist-info → cogames-0.3.68.dist-info}/entry_points.txt +0 -0
  140. {cogames-0.3.64.dist-info → cogames-0.3.68.dist-info}/licenses/LICENSE +0 -0
  141. {cogames-0.3.64.dist-info → cogames-0.3.68.dist-info}/top_level.txt +0 -0
@@ -9,11 +9,14 @@ energy regen, move cost, and capacity limits.
9
9
  from __future__ import annotations
10
10
 
11
11
  import logging
12
- from typing import override
12
+ from typing import TYPE_CHECKING, override
13
13
 
14
14
  from pydantic import Field
15
15
 
16
- from cogames.cogs_vs_clips.mission import Mission, MissionVariant
16
+ from cogames.core import CoGameMissionVariant
17
+
18
+ if TYPE_CHECKING:
19
+ from cogames.cogs_vs_clips.mission import CvCMission
17
20
  from mettagrid.config.mettagrid_config import MettaGridConfig
18
21
 
19
22
  logger = logging.getLogger(__name__)
@@ -28,41 +31,26 @@ ENERGY_REGEN_FLOOR = 0
28
31
  # =============================================================================
29
32
 
30
33
 
31
- class DifficultyLevel(MissionVariant):
34
+ class DifficultyLevel(CoGameMissionVariant):
32
35
  """Configuration for a difficulty level."""
33
36
 
34
37
  name: str = Field(description="Difficulty name (easy, medium, hard, brutal, etc.)")
35
38
  description: str = Field(description="What makes this difficulty challenging", default="")
36
39
 
37
- # Energy regen multiplier (relative to mission baseline)
38
- energy_regen_mult: float = Field(default=1.0)
39
-
40
- # Absolute overrides (if set, ignore multipliers)
41
- energy_regen_override: int | None = Field(default=None)
40
+ # Solar override (if set, overrides weather day/night deltas)
41
+ solar_override: int | None = Field(default=None)
42
42
  move_energy_cost_override: int | None = Field(default=None)
43
43
  energy_capacity_override: int | None = Field(default=None)
44
44
  cargo_capacity_override: int | None = Field(default=None)
45
45
  max_steps_override: int | None = Field(default=None)
46
46
 
47
47
  @override
48
- def modify_mission(self, mission: Mission):
48
+ def modify_mission(self, mission: CvCMission):
49
49
  """Apply a difficulty level to a mission instance."""
50
- # Energy regen
51
- if self.energy_regen_override is not None:
52
- mission.cog.energy_regen = self.energy_regen_override
53
- else:
54
- mission.cog.energy_regen = max(0, int(mission.cog.energy_regen * self.energy_regen_mult))
55
-
56
- # Mission-level overrides
57
- if self.move_energy_cost_override is not None:
58
- mission.cog.move_energy_cost = self.move_energy_cost_override
59
- if self.energy_capacity_override is not None:
60
- mission.cog.energy_limit = self.energy_capacity_override
61
- if self.cargo_capacity_override is not None:
62
- mission.cog.cargo_limit = self.cargo_capacity_override
50
+ pass # No mission-level modifications needed currently
63
51
 
64
52
  @override
65
- def modify_env(self, mission: Mission, env: MettaGridConfig):
53
+ def modify_env(self, mission: CvCMission, env: MettaGridConfig):
66
54
  if self.max_steps_override is not None:
67
55
  env.game.max_steps = self.max_steps_override
68
56
 
@@ -79,20 +67,20 @@ STANDARD = DifficultyLevel(
79
67
  HARD = DifficultyLevel(
80
68
  name="hard",
81
69
  description="Minimal passive regen and higher move cost",
82
- energy_regen_override=1, # Minimal regen prevents deadlock
70
+ solar_override=1, # Minimal regen prevents deadlock
83
71
  move_energy_cost_override=2,
84
72
  )
85
73
 
86
74
  SINGLE_USE = DifficultyLevel(
87
75
  name="single_use",
88
76
  description="Minimal regen - no second chances",
89
- energy_regen_override=1,
77
+ solar_override=1,
90
78
  )
91
79
 
92
80
  SPEED_RUN = DifficultyLevel(
93
81
  name="speed_run",
94
82
  description="Short clock, cheap movement",
95
- energy_regen_override=2,
83
+ solar_override=2,
96
84
  move_energy_cost_override=1,
97
85
  max_steps_override=600,
98
86
  )
@@ -100,7 +88,7 @@ SPEED_RUN = DifficultyLevel(
100
88
  ENERGY_CRISIS = DifficultyLevel(
101
89
  name="energy_crisis",
102
90
  description="Minimal passive regen - plan every move",
103
- energy_regen_override=1, # Minimal regen prevents deadlock
91
+ solar_override=1, # Minimal regen prevents deadlock
104
92
  )
105
93
 
106
94
  # Export variants for use with --variant CLI flag.
@@ -125,7 +113,7 @@ def list_difficulties() -> None:
125
113
  print("=" * 80)
126
114
  for diff in DIFFICULTY_VARIANTS:
127
115
  print(f"\n{diff.name.upper()}: {diff.description}")
128
- print(f" Energy regen mult: {diff.energy_regen_mult}")
116
+ print(f" Solar override: {diff.solar_override}")
129
117
 
130
118
 
131
119
  if __name__ == "__main__":
@@ -2,22 +2,18 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
 
5
- from cogames.cogs_vs_clips.mission import Mission, Site
6
- from cogames.cogs_vs_clips.procedural import MachinaArena
5
+ from cogames.cogs_vs_clips.mission import CvCMission
7
6
  from cogames.cogs_vs_clips.sites import HELLO_WORLD
7
+ from cogames.cogs_vs_clips.terrain import MachinaArena
8
8
  from cogames.cogs_vs_clips.variants import (
9
9
  DarkSideVariant,
10
- DistantResourcesVariant,
11
- EmptyBaseVariant,
12
- PackRatVariant,
13
- QuadrantBuildingsVariant,
14
- SingleResourceUniformVariant,
15
10
  )
11
+ from cogames.core import CoGameSite
16
12
  from mettagrid.mapgen.mapgen import MapGen
17
13
 
18
14
  logger = logging.getLogger(__name__)
19
15
 
20
- SMALL_HELLO_WORLD = Site(
16
+ SMALL_HELLO_WORLD = CoGameSite(
21
17
  name="small_hello_world",
22
18
  description="Small hello world map.",
23
19
  map_builder=MapGen.Config(width=50, height=50, instance=MachinaArena.Config(spawn_count=20)),
@@ -25,7 +21,7 @@ SMALL_HELLO_WORLD = Site(
25
21
  max_cogs=20,
26
22
  )
27
23
 
28
- MEDIUM_HELLO_WORLD = Site(
24
+ MEDIUM_HELLO_WORLD = CoGameSite(
29
25
  name="medium_hello_world",
30
26
  description="Medium hello world map.",
31
27
  map_builder=MapGen.Config(width=100, height=100, instance=MachinaArena.Config(spawn_count=20)),
@@ -33,7 +29,7 @@ MEDIUM_HELLO_WORLD = Site(
33
29
  max_cogs=20,
34
30
  )
35
31
 
36
- LARGE_HELLO_WORLD = Site(
32
+ LARGE_HELLO_WORLD = CoGameSite(
37
33
  name="large_hello_world",
38
34
  description="Large hello world map.",
39
35
  map_builder=MapGen.Config(width=150, height=150, instance=MachinaArena.Config(spawn_count=20)),
@@ -41,65 +37,17 @@ LARGE_HELLO_WORLD = Site(
41
37
  max_cogs=20,
42
38
  )
43
39
 
44
- # Resource Bottleneck evals
45
- OxygenBottleneck = Mission(
46
- name="oxygen_bottleneck",
47
- description="Oxygen is the limiting resource; agents must prioritize oxygen over other resources.",
48
- site=HELLO_WORLD,
49
- variants=[
50
- EmptyBaseVariant(missing=["oxygen_extractor"]),
51
- SingleResourceUniformVariant(building_name="oxygen_extractor"),
52
- PackRatVariant(),
53
- ],
54
- )
55
-
56
40
  # Energy Starved evals
57
- EnergyStarved = Mission(
41
+ EnergyStarved = CvCMission(
58
42
  name="energy_starved",
59
43
  description="Energy is the limiting resource; agents must prioritize energy over other resources.",
60
44
  site=HELLO_WORLD,
61
45
  variants=[
62
- EmptyBaseVariant(),
63
46
  DarkSideVariant(),
64
47
  ],
65
48
  )
66
49
 
67
- # Collect Distant Resources evals
68
- DistantResources = Mission(
69
- name="distant_resources",
70
- description="Resources scattered far from base; heavy routing coordination.",
71
- site=HELLO_WORLD,
72
- variants=[
73
- EmptyBaseVariant(),
74
- DistantResourcesVariant(),
75
- ],
76
- )
77
-
78
- # Divide and Conquer evals
79
- QuadrantBuildings = Mission(
80
- name="quadrant_buildings",
81
- description="Place buildings in the four quadrants of the map.",
82
- site=HELLO_WORLD,
83
- variants=[
84
- EmptyBaseVariant(),
85
- QuadrantBuildingsVariant(),
86
- ],
87
- )
88
-
89
- EasyHeartsMission = Mission(
90
- name="easy_hearts",
91
- description="Simplified heart crafting with generous caps and extractor base.",
92
- site=HELLO_WORLD,
93
- variants=[
94
- PackRatVariant(),
95
- ],
96
- )
97
-
98
50
 
99
- EVAL_MISSIONS: list[Mission] = [
100
- OxygenBottleneck,
51
+ EVAL_MISSIONS: list[CvCMission] = [
101
52
  EnergyStarved,
102
- DistantResources,
103
- QuadrantBuildings,
104
- EasyHeartsMission,
105
53
  ]
@@ -5,26 +5,24 @@ from __future__ import annotations
5
5
 
6
6
  import logging
7
7
 
8
- from cogames.cogs_vs_clips.mission import Mission, Site
9
- from cogames.cogs_vs_clips.procedural import MachinaArena
8
+ from cogames.cogs_vs_clips.mission import CvCMission
10
9
  from cogames.cogs_vs_clips.sites import HELLO_WORLD, TRAINING_FACILITY
10
+ from cogames.cogs_vs_clips.terrain import MachinaArena
11
11
  from cogames.cogs_vs_clips.variants import (
12
- CompassVariant,
13
12
  DarkSideVariant,
14
13
  DistantResourcesVariant,
15
14
  EmptyBaseVariant,
16
15
  EnergizedVariant,
17
- PackRatVariant,
18
16
  QuadrantBuildingsVariant,
19
- RoughTerrainVariant,
20
17
  SingleResourceUniformVariant,
21
18
  SuperChargedVariant,
22
19
  )
20
+ from cogames.core import CoGameSite
23
21
  from mettagrid.mapgen.mapgen import MapGen
24
22
 
25
23
  logger = logging.getLogger(__name__)
26
24
 
27
- SMALL_HELLO_WORLD = Site(
25
+ SMALL_HELLO_WORLD = CoGameSite(
28
26
  name="small_hello_world",
29
27
  description="Small hello world map.",
30
28
  map_builder=MapGen.Config(width=50, height=50, instance=MachinaArena.Config(spawn_count=20)),
@@ -32,7 +30,7 @@ SMALL_HELLO_WORLD = Site(
32
30
  max_cogs=20,
33
31
  )
34
32
 
35
- MEDIUM_HELLO_WORLD = Site(
33
+ MEDIUM_HELLO_WORLD = CoGameSite(
36
34
  name="medium_hello_world",
37
35
  description="Medium hello world map.",
38
36
  map_builder=MapGen.Config(width=100, height=100, instance=MachinaArena.Config(spawn_count=20)),
@@ -40,7 +38,7 @@ MEDIUM_HELLO_WORLD = Site(
40
38
  max_cogs=20,
41
39
  )
42
40
 
43
- LARGE_HELLO_WORLD = Site(
41
+ LARGE_HELLO_WORLD = CoGameSite(
44
42
  name="large_hello_world",
45
43
  description="Large hello world map.",
46
44
  map_builder=MapGen.Config(width=500, height=500, instance=MachinaArena.Config(spawn_count=20)),
@@ -49,19 +47,19 @@ LARGE_HELLO_WORLD = Site(
49
47
  )
50
48
 
51
49
  # Resource Bottleneck evals
52
- OxygenBottleneck = Mission(
50
+ OxygenBottleneck = CvCMission(
53
51
  name="oxygen_bottleneck",
54
52
  description="Oxygen is the limiting resource; agents must prioritize oxygen over other resources.",
55
53
  site=HELLO_WORLD,
56
54
  variants=[
57
55
  EmptyBaseVariant(missing=["oxygen_extractor"]),
58
56
  SingleResourceUniformVariant(building_name="oxygen_extractor"),
59
- PackRatVariant(),
57
+ EnergizedVariant(),
60
58
  ],
61
59
  )
62
60
 
63
61
  # Energy Starved evals
64
- EnergyStarved = Mission(
62
+ EnergyStarved = CvCMission(
65
63
  name="energy_starved",
66
64
  description="Energy is the limiting resource; agents must prioritize energy over other resources.",
67
65
  site=HELLO_WORLD,
@@ -74,17 +72,17 @@ EnergyStarved = Mission(
74
72
  # Curated difficulty tiers per mission
75
73
  # ------------------------------------------------------------
76
74
  # Oxygen Bottleneck
77
- OxygenBottleneckEasy = Mission(
75
+ OxygenBottleneckEasy = CvCMission(
78
76
  name="oxygen_bottleneck_easy",
79
77
  description="Easy: tuned oxygen focus with simple layout and generous capacities.",
80
78
  site=HELLO_WORLD,
81
79
  variants=[
82
80
  SingleResourceUniformVariant(building_name="oxygen_extractor"),
83
- PackRatVariant(),
81
+ EnergizedVariant(),
84
82
  ],
85
83
  )
86
84
 
87
- OxygenBottleneckStandard = Mission(
85
+ OxygenBottleneckStandard = CvCMission(
88
86
  name="oxygen_bottleneck_standard",
89
87
  description="Standard: oxygen is the bottleneck; extractor missing at base.",
90
88
  site=HELLO_WORLD,
@@ -93,18 +91,18 @@ OxygenBottleneckStandard = Mission(
93
91
  ],
94
92
  )
95
93
 
96
- OxygenBottleneckHard = Mission(
94
+ OxygenBottleneckHard = CvCMission(
97
95
  name="oxygen_bottleneck_hard",
98
- description="Hard: oxygen bottleneck plus rough terrain.",
96
+ description="Hard: oxygen bottleneck with dark side.",
99
97
  site=HELLO_WORLD,
100
98
  variants=[
101
99
  EmptyBaseVariant(missing=["oxygen_extractor"]),
102
- RoughTerrainVariant(),
100
+ DarkSideVariant(),
103
101
  ],
104
102
  )
105
103
 
106
104
  # Energy Starved
107
- EnergyStarvedEasy = Mission(
105
+ EnergyStarvedEasy = CvCMission(
108
106
  name="energy_starved_easy",
109
107
  description="Easy: abundant energy regen and capacity.",
110
108
  site=HELLO_WORLD,
@@ -114,7 +112,7 @@ EnergyStarvedEasy = Mission(
114
112
  ],
115
113
  )
116
114
 
117
- EnergyStarvedStandard = Mission(
115
+ EnergyStarvedStandard = CvCMission(
118
116
  name="energy_starved_standard",
119
117
  description="Standard: energy is the limiting resource with dark-side regen.",
120
118
  site=HELLO_WORLD,
@@ -123,18 +121,17 @@ EnergyStarvedStandard = Mission(
123
121
  ],
124
122
  )
125
123
 
126
- EnergyStarvedHard = Mission(
124
+ EnergyStarvedHard = CvCMission(
127
125
  name="energy_starved_hard",
128
- description="Hard: energy bottleneck with dark side and rough terrain.",
126
+ description="Hard: energy bottleneck with dark side.",
129
127
  site=HELLO_WORLD,
130
128
  variants=[
131
129
  DarkSideVariant(),
132
- RoughTerrainVariant(),
133
130
  ],
134
131
  )
135
132
 
136
133
  # Collect Distant Resources evals
137
- DistantResources = Mission(
134
+ DistantResources = CvCMission(
138
135
  name="distant_resources",
139
136
  description="Resources scattered far from base; heavy routing coordination.",
140
137
  site=HELLO_WORLD,
@@ -145,39 +142,37 @@ DistantResources = Mission(
145
142
  )
146
143
 
147
144
  # Distant Resources tiers
148
- DistantResourcesEasy = Mission(
145
+ DistantResourcesEasy = CvCMission(
149
146
  name="distant_resources_easy",
150
- description="Easy: simplified distribution and navigation aids.",
147
+ description="Easy: simplified distribution with generous capacity.",
151
148
  site=HELLO_WORLD,
152
149
  variants=[
153
- CompassVariant(),
154
- PackRatVariant(),
150
+ EnergizedVariant(),
155
151
  DistantResourcesVariant(),
156
152
  ],
157
153
  )
158
154
 
159
- DistantResourcesStandard = Mission(
155
+ DistantResourcesStandard = CvCMission(
160
156
  name="distant_resources_standard",
161
157
  description="Standard: resources scattered far from base.",
162
158
  site=HELLO_WORLD,
163
159
  variants=[
164
- CompassVariant(),
165
160
  DistantResourcesVariant(),
166
161
  ],
167
162
  )
168
163
 
169
- DistantResourcesHard = Mission(
164
+ DistantResourcesHard = CvCMission(
170
165
  name="distant_resources_hard",
171
- description="Hard: distant resources with rough terrain.",
166
+ description="Hard: distant resources with dark side.",
172
167
  site=HELLO_WORLD,
173
168
  variants=[
174
169
  DistantResourcesVariant(),
175
- RoughTerrainVariant(),
170
+ DarkSideVariant(),
176
171
  ],
177
172
  )
178
173
 
179
174
  # Divide and Conquer evals
180
- QuadrantBuildings = Mission(
175
+ QuadrantBuildings = CvCMission(
181
176
  name="quadrant_buildings",
182
177
  description="Place buildings in the four quadrants of the map.",
183
178
  site=HELLO_WORLD,
@@ -188,18 +183,17 @@ QuadrantBuildings = Mission(
188
183
  )
189
184
 
190
185
  # Quadrant Buildings tiers
191
- QuadrantBuildingsEasy = Mission(
186
+ QuadrantBuildingsEasy = CvCMission(
192
187
  name="quadrant_buildings_easy",
193
- description="Easy: buildings in quadrants with navigation aid and inventory boost.",
188
+ description="Easy: buildings in quadrants with energy boost.",
194
189
  site=HELLO_WORLD,
195
190
  variants=[
196
191
  QuadrantBuildingsVariant(),
197
- CompassVariant(),
198
- PackRatVariant(),
192
+ EnergizedVariant(),
199
193
  ],
200
194
  )
201
195
 
202
- QuadrantBuildingsStandard = Mission(
196
+ QuadrantBuildingsStandard = CvCMission(
203
197
  name="quadrant_buildings_standard",
204
198
  description="Standard: buildings placed in quadrants.",
205
199
  site=HELLO_WORLD,
@@ -209,54 +203,54 @@ QuadrantBuildingsStandard = Mission(
209
203
  ],
210
204
  )
211
205
 
212
- QuadrantBuildingsHard = Mission(
206
+ QuadrantBuildingsHard = CvCMission(
213
207
  name="quadrant_buildings_hard",
214
- description="Hard: quadrant distribution with empty base and rough terrain.",
208
+ description="Hard: quadrant distribution with empty base and dark side.",
215
209
  site=HELLO_WORLD,
216
210
  variants=[
217
211
  QuadrantBuildingsVariant(),
218
212
  EmptyBaseVariant(),
219
- RoughTerrainVariant(),
213
+ DarkSideVariant(),
220
214
  ],
221
215
  )
222
216
 
223
- EasyHeartsTraining = Mission(
217
+ EasyHeartsTraining = CvCMission(
224
218
  name="easy_hearts_training",
225
- description="Simplified heart crafting with generous caps and extractor base.",
219
+ description="Simplified heart crafting with generous energy.",
226
220
  site=TRAINING_FACILITY,
227
221
  variants=[
228
- PackRatVariant(),
222
+ EnergizedVariant(),
229
223
  ],
230
224
  )
231
225
 
232
- EasyHeartsSmallWorld = Mission(
226
+ EasyHeartsSmallWorld = CvCMission(
233
227
  name="easy_small_hearts",
234
- description="Simplified heart crafting with generous caps and extractor base.",
228
+ description="Simplified heart crafting with generous energy.",
235
229
  site=SMALL_HELLO_WORLD,
236
230
  variants=[
237
- PackRatVariant(),
231
+ EnergizedVariant(),
238
232
  ],
239
233
  )
240
234
 
241
- EasyHeartsMediumWorld = Mission(
235
+ EasyHeartsMediumWorld = CvCMission(
242
236
  name="easy_medium_hearts",
243
- description="Simplified heart crafting with generous caps and extractor base.",
237
+ description="Simplified heart crafting with generous energy.",
244
238
  site=MEDIUM_HELLO_WORLD,
245
239
  variants=[
246
- PackRatVariant(),
240
+ EnergizedVariant(),
247
241
  ],
248
242
  )
249
243
 
250
- EasyHeartsLargeWorld = Mission(
244
+ EasyHeartsLargeWorld = CvCMission(
251
245
  name="easy_large_hearts",
252
- description="Simplified heart crafting with generous caps and extractor base.",
246
+ description="Simplified heart crafting with generous energy.",
253
247
  site=LARGE_HELLO_WORLD,
254
248
  variants=[
255
- PackRatVariant(),
249
+ EnergizedVariant(),
256
250
  ],
257
251
  )
258
252
 
259
- EVAL_MISSIONS: list[Mission] = [
253
+ EVAL_MISSIONS: list[CvCMission] = [
260
254
  # Oxygen bottleneck tiers
261
255
  OxygenBottleneckEasy,
262
256
  OxygenBottleneckStandard,