cogames 0.3.64__py3-none-any.whl → 0.3.65__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.
- cogames/cli/mission.py +25 -35
- cogames/cli/submit.py +1 -1
- cogames/cogs_vs_clips/clips.py +86 -0
- cogames/cogs_vs_clips/cog.py +14 -7
- cogames/cogs_vs_clips/cogsguard_tutorial.py +10 -11
- cogames/cogs_vs_clips/config.py +38 -0
- cogames/cogs_vs_clips/{cogs_vs_clips_mapgen.md → docs/cogs_vs_clips_mapgen.md} +6 -7
- cogames/cogs_vs_clips/evals/README.md +4 -4
- cogames/cogs_vs_clips/evals/cogsguard_evals.py +21 -6
- cogames/cogs_vs_clips/evals/diagnostic_evals.py +13 -100
- cogames/cogs_vs_clips/evals/difficulty_variants.py +9 -18
- cogames/cogs_vs_clips/evals/integrated_evals.py +8 -60
- cogames/cogs_vs_clips/evals/spanning_evals.py +48 -54
- cogames/cogs_vs_clips/mission.py +65 -277
- cogames/cogs_vs_clips/missions.py +16 -26
- cogames/cogs_vs_clips/sites.py +35 -25
- cogames/cogs_vs_clips/stations.py +33 -82
- cogames/cogs_vs_clips/team.py +44 -0
- cogames/cogs_vs_clips/{procedural.py → terrain.py} +12 -6
- cogames/cogs_vs_clips/variants.py +41 -118
- cogames/core.py +87 -0
- cogames/verbose.py +2 -2
- {cogames-0.3.64.dist-info → cogames-0.3.65.dist-info}/METADATA +2 -2
- {cogames-0.3.64.dist-info → cogames-0.3.65.dist-info}/RECORD +28 -27
- cogames/cogs_vs_clips/cogsguard_reward_variants.py +0 -153
- cogames/cogs_vs_clips/mission_utils.py +0 -19
- cogames/cogs_vs_clips/tutorial_missions.py +0 -25
- {cogames-0.3.64.dist-info → cogames-0.3.65.dist-info}/WHEEL +0 -0
- {cogames-0.3.64.dist-info → cogames-0.3.65.dist-info}/entry_points.txt +0 -0
- {cogames-0.3.64.dist-info → cogames-0.3.65.dist-info}/licenses/LICENSE +0 -0
- {cogames-0.3.64.dist-info → cogames-0.3.65.dist-info}/top_level.txt +0 -0
cogames/cogs_vs_clips/mission.py
CHANGED
|
@@ -1,188 +1,70 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from abc import ABC
|
|
4
|
-
from typing import TypeVar, override
|
|
5
|
-
|
|
6
3
|
from pydantic import Field
|
|
7
|
-
from typing_extensions import Self
|
|
8
4
|
|
|
5
|
+
from cogames.cogs_vs_clips.clips import ClipsConfig
|
|
9
6
|
from cogames.cogs_vs_clips.cog import CogConfig
|
|
7
|
+
from cogames.cogs_vs_clips.config import CvCConfig
|
|
10
8
|
from cogames.cogs_vs_clips.stations import (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
CvCChestConfig,
|
|
10
|
+
CvCExtractorConfig,
|
|
11
|
+
CvCGearStationConfig,
|
|
12
|
+
CvCHubConfig,
|
|
13
|
+
CvCJunctionConfig,
|
|
14
14
|
CvCWallConfig,
|
|
15
|
-
GearStationConfig,
|
|
16
|
-
HubConfig,
|
|
17
|
-
JunctionConfig,
|
|
18
|
-
SimpleExtractorConfig,
|
|
19
15
|
)
|
|
20
|
-
from
|
|
16
|
+
from cogames.cogs_vs_clips.team import CogTeam
|
|
17
|
+
from cogames.cogs_vs_clips.variants import NumCogsVariant
|
|
18
|
+
from cogames.core import (
|
|
19
|
+
MAP_MISSION_DELIMITER,
|
|
20
|
+
CoGameMission,
|
|
21
|
+
CoGameMissionVariant,
|
|
22
|
+
CoGameSite,
|
|
23
|
+
)
|
|
21
24
|
from mettagrid.config.action_config import (
|
|
22
25
|
ActionsConfig,
|
|
23
26
|
ChangeVibeActionConfig,
|
|
24
27
|
MoveActionConfig,
|
|
25
28
|
NoopActionConfig,
|
|
26
29
|
)
|
|
27
|
-
from mettagrid.config.event_config import EventConfig, periodic
|
|
28
|
-
from mettagrid.config.filter import isAlignedTo, isNear
|
|
29
30
|
from mettagrid.config.game_value import inv
|
|
30
|
-
from mettagrid.config.
|
|
31
|
-
from mettagrid.config.mettagrid_config import (
|
|
32
|
-
CollectiveConfig,
|
|
33
|
-
GameConfig,
|
|
34
|
-
InventoryConfig,
|
|
35
|
-
MettaGridConfig,
|
|
36
|
-
ResourceLimitsConfig,
|
|
37
|
-
)
|
|
38
|
-
from mettagrid.config.mutation import alignTo
|
|
31
|
+
from mettagrid.config.mettagrid_config import GameConfig, MettaGridConfig
|
|
39
32
|
from mettagrid.config.obs_config import GlobalObsConfig, ObsConfig
|
|
40
|
-
from mettagrid.config.reward_config import numObjects, reward
|
|
41
|
-
from mettagrid.config.tag import typeTag
|
|
42
|
-
from mettagrid.config.vibes import Vibe
|
|
43
33
|
from mettagrid.map_builder.map_builder import AnyMapBuilderConfig
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
name: str
|
|
53
|
-
description: str = Field(default="")
|
|
54
|
-
|
|
55
|
-
def modify_mission(self, mission: MissionBase) -> None:
|
|
56
|
-
# Override this method to modify the mission.
|
|
57
|
-
# Variants are allowed to modify the mission in-place - it's guaranteed to be a one-time only instance.
|
|
58
|
-
pass
|
|
59
|
-
|
|
60
|
-
def modify_env(self, mission: MissionBase, env: MettaGridConfig) -> None:
|
|
61
|
-
# Override this method to modify the produced environment.
|
|
62
|
-
# Variants are allowed to modify the environment in-place.
|
|
63
|
-
pass
|
|
64
|
-
|
|
65
|
-
def compat(self, mission: MissionBase) -> bool:
|
|
66
|
-
"""Check if this variant is compatible with the given mission.
|
|
67
|
-
|
|
68
|
-
Returns True if the variant can be safely applied to the mission.
|
|
69
|
-
Override this method to add compatibility checks.
|
|
70
|
-
"""
|
|
71
|
-
return True
|
|
72
|
-
|
|
73
|
-
def apply(self, mission: TMission) -> TMission:
|
|
74
|
-
mission = mission.model_copy(deep=True)
|
|
75
|
-
mission.variants.append(self)
|
|
76
|
-
self.modify_mission(mission)
|
|
77
|
-
return mission
|
|
78
|
-
|
|
79
|
-
# Temporary helper useful as long as we have one-time variants in missions.py file.
|
|
80
|
-
def as_mission(self, name: str, description: str, site: Site) -> Mission:
|
|
81
|
-
return Mission(
|
|
82
|
-
name=name,
|
|
83
|
-
description=description,
|
|
84
|
-
site=site,
|
|
85
|
-
variants=[self],
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class NumCogsVariant(MissionVariant):
|
|
90
|
-
name: str = "num_cogs"
|
|
91
|
-
description: str = "Set the number of cogs for the mission."
|
|
92
|
-
num_cogs: int
|
|
93
|
-
|
|
94
|
-
@override
|
|
95
|
-
def modify_mission(self, mission: Mission) -> None:
|
|
96
|
-
if self.num_cogs < mission.site.min_cogs or self.num_cogs > mission.site.max_cogs:
|
|
97
|
-
raise ValueError(
|
|
98
|
-
f"Invalid number of cogs for {mission.site.name}: {self.num_cogs}. "
|
|
99
|
-
+ f"Must be between {mission.site.min_cogs} and {mission.site.max_cogs}"
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
mission.num_cogs = self.num_cogs
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class Site(Config):
|
|
106
|
-
name: str
|
|
107
|
-
description: str
|
|
108
|
-
map_builder: AnyMapBuilderConfig
|
|
109
|
-
|
|
110
|
-
min_cogs: int = Field(default=1, ge=1)
|
|
111
|
-
max_cogs: int = Field(default=1000, ge=1)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
MAP_MISSION_DELIMITER = "."
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class MissionBase(Config, ABC):
|
|
118
|
-
"""Base class for Mission configurations with common fields and methods."""
|
|
119
|
-
|
|
120
|
-
name: str
|
|
121
|
-
description: str
|
|
122
|
-
site: Site
|
|
123
|
-
num_cogs: int | None = None
|
|
124
|
-
|
|
125
|
-
# Variants are applied to the mission immediately, and to its env when make_env is called
|
|
126
|
-
variants: list[MissionVariant] = Field(default_factory=list)
|
|
127
|
-
|
|
128
|
-
max_steps: int = Field(default=10000)
|
|
129
|
-
|
|
130
|
-
def __init__(self, **kwargs):
|
|
131
|
-
super().__init__(**kwargs)
|
|
132
|
-
# Can't call `variant.apply` here because it will create a new mission instance
|
|
133
|
-
for variant in self.variants:
|
|
134
|
-
variant.modify_mission(self)
|
|
135
|
-
|
|
136
|
-
def with_variants(self, variants: list[MissionVariant]) -> Self:
|
|
137
|
-
mission = self
|
|
138
|
-
for variant in variants:
|
|
139
|
-
mission = variant.apply(mission)
|
|
140
|
-
return mission
|
|
141
|
-
|
|
142
|
-
def full_name(self) -> str:
|
|
143
|
-
return f"{self.site.name}{MAP_MISSION_DELIMITER}{self.name}"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
# CogsGuard vibes
|
|
147
|
-
COGSGUARD_VIBES = [
|
|
148
|
-
Vibe("😐", "default"),
|
|
149
|
-
Vibe("❤️", "heart"),
|
|
150
|
-
Vibe("⚙️", "gear"),
|
|
151
|
-
Vibe("🌀", "scrambler"),
|
|
152
|
-
Vibe("🔗", "aligner"),
|
|
153
|
-
Vibe("⛏️", "miner"),
|
|
154
|
-
Vibe("🔭", "scout"),
|
|
35
|
+
__all__ = [
|
|
36
|
+
"MAP_MISSION_DELIMITER",
|
|
37
|
+
"CoGameMission",
|
|
38
|
+
"CoGameMissionVariant",
|
|
39
|
+
"CoGameSite",
|
|
40
|
+
"CvCMission",
|
|
41
|
+
"NumCogsVariant",
|
|
155
42
|
]
|
|
156
43
|
|
|
157
44
|
|
|
158
|
-
class
|
|
45
|
+
class CvCMission(CoGameMission):
|
|
159
46
|
"""Mission configuration for CogsGuard game mode."""
|
|
160
47
|
|
|
161
|
-
|
|
162
|
-
cog: CogConfig = Field(default_factory=CogConfig)
|
|
163
|
-
|
|
164
|
-
wealth: int = Field(default=1)
|
|
48
|
+
max_steps: int = Field(default=10000)
|
|
165
49
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
50
|
+
cog: CogConfig = Field(default_factory=lambda: CogConfig())
|
|
51
|
+
teams: dict[str, CogTeam] = Field(
|
|
52
|
+
default_factory=lambda: {
|
|
53
|
+
"cogs": CogTeam(name="cogs", num_agents=8, wealth=1),
|
|
54
|
+
}
|
|
55
|
+
)
|
|
172
56
|
|
|
173
|
-
|
|
174
|
-
# Note: must start after initial_clips fires at timestep 10 (events fire alphabetically)
|
|
175
|
-
clips_scramble_start: int = Field(default=50)
|
|
176
|
-
clips_scramble_interval: int = Field(default=100)
|
|
177
|
-
clips_scramble_radius: int = Field(default=25)
|
|
57
|
+
clips: ClipsConfig = Field(default_factory=lambda: ClipsConfig())
|
|
178
58
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
59
|
+
@property
|
|
60
|
+
def num_agents(self) -> int:
|
|
61
|
+
if self.num_cogs is not None:
|
|
62
|
+
return self.num_cogs
|
|
63
|
+
return sum(team.num_agents for team in self.teams.values())
|
|
183
64
|
|
|
184
|
-
|
|
185
|
-
|
|
65
|
+
def map_builder(self) -> AnyMapBuilderConfig:
|
|
66
|
+
"""Return the map builder config. Override in subclasses for custom map generation."""
|
|
67
|
+
return self.site.map_builder
|
|
186
68
|
|
|
187
69
|
def make_env(self) -> MettaGridConfig:
|
|
188
70
|
"""Create a MettaGridConfig from this mission.
|
|
@@ -192,129 +74,41 @@ class Mission(MissionBase):
|
|
|
192
74
|
Returns:
|
|
193
75
|
MettaGridConfig ready for environment creation
|
|
194
76
|
"""
|
|
195
|
-
map_builder = self.site.map_builder
|
|
196
|
-
num_cogs = self.num_cogs if self.num_cogs is not None else self.site.min_cogs
|
|
197
|
-
|
|
198
|
-
gear = GEAR
|
|
199
|
-
elements = ELEMENTS
|
|
200
|
-
resources_list = ["energy", "heart", "hp", "influence", *elements, *gear]
|
|
201
|
-
vibe_names = [vibe.name for vibe in COGSGUARD_VIBES]
|
|
202
|
-
|
|
203
|
-
extractor_objects = {
|
|
204
|
-
f"{resource}_extractor": SimpleExtractorConfig(resource=resource).station_cfg() for resource in elements
|
|
205
|
-
}
|
|
206
|
-
gear_objects = {f"{g}_station": GearStationConfig(gear_type=g).station_cfg() for g in gear}
|
|
207
|
-
|
|
208
|
-
# Create inventory observations for collective resources
|
|
209
|
-
collective_obs = [inv(f"collective.{resource}") for resource in elements]
|
|
210
77
|
|
|
211
78
|
game = GameConfig(
|
|
212
|
-
map_builder=map_builder,
|
|
79
|
+
map_builder=self.map_builder(),
|
|
213
80
|
max_steps=self.max_steps,
|
|
214
|
-
num_agents=
|
|
215
|
-
resource_names=
|
|
216
|
-
vibe_names=
|
|
217
|
-
obs=ObsConfig(
|
|
81
|
+
num_agents=self.num_agents,
|
|
82
|
+
resource_names=CvCConfig.RESOURCES,
|
|
83
|
+
vibe_names=CvCConfig.VIBE_NAMES,
|
|
84
|
+
obs=ObsConfig(
|
|
85
|
+
global_obs=GlobalObsConfig(
|
|
86
|
+
obs=[inv(f"collective.{resource}") for resource in CvCConfig.ELEMENTS], local_position=True
|
|
87
|
+
)
|
|
88
|
+
),
|
|
218
89
|
actions=ActionsConfig(
|
|
219
|
-
move=MoveActionConfig(consumed_resources=
|
|
90
|
+
move=MoveActionConfig(consumed_resources=self.cog.action_cost),
|
|
220
91
|
noop=NoopActionConfig(),
|
|
221
|
-
change_vibe=ChangeVibeActionConfig(vibes=
|
|
222
|
-
),
|
|
223
|
-
agent=self.cog.agent_config(gear=gear, elements=elements).model_copy(
|
|
224
|
-
update={
|
|
225
|
-
"rewards": {
|
|
226
|
-
"aligned_junction_held": reward(
|
|
227
|
-
game_stat("collective.aligned.junction.held"),
|
|
228
|
-
weight=1.0 / self.max_steps,
|
|
229
|
-
denoms=[numObjects("junction")],
|
|
230
|
-
),
|
|
231
|
-
},
|
|
232
|
-
}
|
|
92
|
+
change_vibe=ChangeVibeActionConfig(vibes=CvCConfig.VIBES),
|
|
233
93
|
),
|
|
94
|
+
agent=self.cog.agent_config(team="cogs", max_steps=self.max_steps),
|
|
95
|
+
agents=[self.cog.agent_config(team="cogs", max_steps=self.max_steps) for _ in range(self.num_agents)],
|
|
234
96
|
objects={
|
|
235
|
-
"wall":
|
|
236
|
-
"hub":
|
|
237
|
-
"junction":
|
|
238
|
-
"chest":
|
|
239
|
-
**
|
|
240
|
-
|
|
97
|
+
"wall": CvCWallConfig().station_cfg(),
|
|
98
|
+
"hub": CvCHubConfig().station_cfg(team="cogs"),
|
|
99
|
+
"junction": CvCJunctionConfig().station_cfg(),
|
|
100
|
+
"chest": CvCChestConfig().station_cfg(team="cogs"),
|
|
101
|
+
**{
|
|
102
|
+
f"{resource}_extractor": CvCExtractorConfig(resource=resource).station_cfg()
|
|
103
|
+
for resource in CvCConfig.ELEMENTS
|
|
104
|
+
},
|
|
105
|
+
**{f"{g}_station": CvCGearStationConfig(gear_type=g).station_cfg(team="cogs") for g in CvCConfig.GEAR},
|
|
241
106
|
},
|
|
242
107
|
collectives={
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
limits={
|
|
246
|
-
"resources": ResourceLimitsConfig(min=10000, resources=elements),
|
|
247
|
-
"hearts": ResourceLimitsConfig(min=65535, resources=["heart"]),
|
|
248
|
-
},
|
|
249
|
-
initial={
|
|
250
|
-
"carbon": self.collective_initial_carbon * self.wealth,
|
|
251
|
-
"oxygen": self.collective_initial_oxygen * self.wealth,
|
|
252
|
-
"germanium": self.collective_initial_germanium * self.wealth,
|
|
253
|
-
"silicon": self.collective_initial_silicon * self.wealth,
|
|
254
|
-
"heart": self.collective_initial_heart * self.wealth,
|
|
255
|
-
},
|
|
256
|
-
),
|
|
257
|
-
),
|
|
258
|
-
"clips": CollectiveConfig(),
|
|
259
|
-
},
|
|
260
|
-
events={
|
|
261
|
-
"initial_clips": EventConfig(
|
|
262
|
-
name="initial_clips",
|
|
263
|
-
target_tag=typeTag("junction"),
|
|
264
|
-
timesteps=[10],
|
|
265
|
-
mutations=[alignTo("clips")],
|
|
266
|
-
max_targets=1,
|
|
267
|
-
),
|
|
268
|
-
"cogs_to_neutral": EventConfig(
|
|
269
|
-
name="cogs_to_neutral",
|
|
270
|
-
target_tag=typeTag("junction"),
|
|
271
|
-
timesteps=periodic(
|
|
272
|
-
start=self.clips_scramble_start,
|
|
273
|
-
period=self.clips_scramble_interval,
|
|
274
|
-
end_period=self.clips_scramble_interval // 5,
|
|
275
|
-
end=self.max_steps,
|
|
276
|
-
),
|
|
277
|
-
filters=[
|
|
278
|
-
isNear(typeTag("junction"), [isAlignedTo("clips")], radius=self.clips_scramble_radius),
|
|
279
|
-
isAlignedTo("cogs"),
|
|
280
|
-
],
|
|
281
|
-
mutations=[alignTo(None)],
|
|
282
|
-
max_targets=1,
|
|
283
|
-
),
|
|
284
|
-
"neutral_to_clips": EventConfig(
|
|
285
|
-
name="neutral_to_clips",
|
|
286
|
-
target_tag=typeTag("junction"),
|
|
287
|
-
timesteps=periodic(
|
|
288
|
-
start=self.clips_align_start,
|
|
289
|
-
period=self.clips_align_interval,
|
|
290
|
-
end_period=self.clips_align_interval // 5,
|
|
291
|
-
end=self.max_steps,
|
|
292
|
-
),
|
|
293
|
-
filters=[
|
|
294
|
-
isNear(typeTag("junction"), [isAlignedTo("clips")], radius=self.clips_align_radius),
|
|
295
|
-
isAlignedTo(None),
|
|
296
|
-
],
|
|
297
|
-
mutations=[alignTo("clips")],
|
|
298
|
-
max_targets=1,
|
|
299
|
-
fallback="cogs_to_neutral",
|
|
300
|
-
),
|
|
301
|
-
# If the Clips can't find any junctions near them, align a random junction
|
|
302
|
-
"presence_check": EventConfig(
|
|
303
|
-
name="presence_check",
|
|
304
|
-
target_tag=typeTag("junction"),
|
|
305
|
-
timesteps=periodic(
|
|
306
|
-
start=self.clips_scramble_start,
|
|
307
|
-
period=self.clips_scramble_interval,
|
|
308
|
-
end=self.max_steps,
|
|
309
|
-
),
|
|
310
|
-
filters=[
|
|
311
|
-
isNear(typeTag("junction"), [isAlignedTo("clips")], radius=self.clips_scramble_radius),
|
|
312
|
-
],
|
|
313
|
-
mutations=[],
|
|
314
|
-
max_targets=1,
|
|
315
|
-
fallback="initial_clips",
|
|
316
|
-
),
|
|
108
|
+
**{team.name: team.collective_config() for team in self.teams.values()},
|
|
109
|
+
"clips": self.clips.collective_config(),
|
|
317
110
|
},
|
|
111
|
+
events=self.clips.events(max_steps=self.max_steps),
|
|
318
112
|
)
|
|
319
113
|
|
|
320
114
|
env = MettaGridConfig(game=game)
|
|
@@ -328,9 +122,3 @@ class Mission(MissionBase):
|
|
|
328
122
|
env.label += f".{variant.name}"
|
|
329
123
|
|
|
330
124
|
return env
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
# Backwards compatibility alias
|
|
334
|
-
CogsGuardMission = Mission
|
|
335
|
-
|
|
336
|
-
AnyMission = Mission
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from functools import lru_cache
|
|
2
2
|
|
|
3
|
-
from cogames.cogs_vs_clips.mission import
|
|
3
|
+
from cogames.cogs_vs_clips.mission import CvCMission
|
|
4
4
|
from cogames.cogs_vs_clips.sites import (
|
|
5
5
|
COGSGUARD_ARENA,
|
|
6
6
|
COGSGUARD_MACHINA_1,
|
|
@@ -11,9 +11,9 @@ from mettagrid.config.mettagrid_config import MettaGridConfig
|
|
|
11
11
|
# CogsGuard Missions
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def make_cogsguard_mission(num_agents: int = 10, max_steps: int = 10000) ->
|
|
14
|
+
def make_cogsguard_mission(num_agents: int = 10, max_steps: int = 10000) -> CvCMission:
|
|
15
15
|
"""Create a CogsGuard mission with configurable parameters (Machina1 layout)."""
|
|
16
|
-
return
|
|
16
|
+
return CvCMission(
|
|
17
17
|
name="basic",
|
|
18
18
|
description="Basic CogsGuard mission (Machina1 layout)",
|
|
19
19
|
site=make_cogsguard_machina1_site(num_agents),
|
|
@@ -22,7 +22,7 @@ def make_cogsguard_mission(num_agents: int = 10, max_steps: int = 10000) -> Miss
|
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
CogsGuardMachina1Mission =
|
|
25
|
+
CogsGuardMachina1Mission = CvCMission(
|
|
26
26
|
name="basic",
|
|
27
27
|
description="CogsGuard Machina1 - compete to control junctions with gear abilities.",
|
|
28
28
|
site=COGSGUARD_MACHINA_1,
|
|
@@ -30,7 +30,7 @@ CogsGuardMachina1Mission = Mission(
|
|
|
30
30
|
max_steps=10000,
|
|
31
31
|
)
|
|
32
32
|
|
|
33
|
-
CogsGuardBasicMission =
|
|
33
|
+
CogsGuardBasicMission = CvCMission(
|
|
34
34
|
name="basic",
|
|
35
35
|
description="CogsGuard Arena - compact training map with gear abilities.",
|
|
36
36
|
site=COGSGUARD_ARENA,
|
|
@@ -39,48 +39,38 @@ CogsGuardBasicMission = Mission(
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
_CORE_MISSIONS: list[
|
|
42
|
+
_CORE_MISSIONS: list[CvCMission] = [
|
|
43
43
|
CogsGuardMachina1Mission,
|
|
44
44
|
CogsGuardBasicMission,
|
|
45
45
|
]
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def get_core_missions() -> list[
|
|
48
|
+
def get_core_missions() -> list[CvCMission]:
|
|
49
49
|
return list(_CORE_MISSIONS)
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def
|
|
53
|
-
"""Get legacy (pre-CogsGuard) missions for backward compatibility.
|
|
54
|
-
|
|
55
|
-
Legacy missions have been removed. Returns empty list.
|
|
56
|
-
"""
|
|
57
|
-
return []
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def _build_eval_missions() -> list[AnyMission]:
|
|
61
|
-
from cogames.cogs_vs_clips.evals.cogsguard_evals import COGSGUARD_EVAL_MISSIONS
|
|
52
|
+
def _build_eval_missions() -> list[CvCMission]:
|
|
62
53
|
from cogames.cogs_vs_clips.evals.integrated_evals import EVAL_MISSIONS as INTEGRATED_EVAL_MISSIONS
|
|
63
54
|
|
|
64
55
|
return [
|
|
65
|
-
*COGSGUARD_EVAL_MISSIONS,
|
|
66
56
|
*INTEGRATED_EVAL_MISSIONS,
|
|
67
57
|
]
|
|
68
58
|
|
|
69
59
|
|
|
70
60
|
@lru_cache(maxsize=1)
|
|
71
|
-
def get_missions() -> list[
|
|
61
|
+
def get_missions() -> list[CvCMission]:
|
|
72
62
|
return [*_CORE_MISSIONS, *_build_eval_missions()]
|
|
73
63
|
|
|
74
64
|
|
|
75
|
-
def
|
|
65
|
+
def make_game(num_cogs: int = 2, map_name: str = "training_facility_open_1.map") -> MettaGridConfig:
|
|
66
|
+
"""Create a default CogsGuard game configuration."""
|
|
67
|
+
mission = make_cogsguard_mission(num_agents=num_cogs)
|
|
68
|
+
return mission.make_env()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def __getattr__(name: str) -> list[CvCMission]:
|
|
76
72
|
if name == "MISSIONS":
|
|
77
73
|
missions = get_missions()
|
|
78
74
|
globals()["MISSIONS"] = missions
|
|
79
75
|
return missions
|
|
80
76
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def make_game(num_cogs: int = 2, map_name: str = "training_facility_open_1.map") -> MettaGridConfig:
|
|
84
|
-
"""Create a default CogsGuard game configuration."""
|
|
85
|
-
mission = make_cogsguard_mission(num_agents=num_cogs)
|
|
86
|
-
return mission.make_env()
|
cogames/cogs_vs_clips/sites.py
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
"""Central site definitions shared across mission modules."""
|
|
2
2
|
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import cast
|
|
4
5
|
|
|
5
|
-
from cogames.cogs_vs_clips.
|
|
6
|
-
from cogames.
|
|
7
|
-
from
|
|
6
|
+
from cogames.cogs_vs_clips.terrain import MachinaArena, RandomTransform, SequentialMachinaArena
|
|
7
|
+
from cogames.core import CoGameSite
|
|
8
|
+
from mettagrid.map_builder.map_builder import MapBuilderConfig
|
|
8
9
|
from mettagrid.mapgen.mapgen import MapGen, MapGenConfig
|
|
9
10
|
from mettagrid.mapgen.scenes.base_hub import BaseHub, BaseHubConfig
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
MAPS_DIR = Path(__file__).resolve().parent.parent / "maps"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_map(map_name: str) -> MapBuilderConfig:
|
|
16
|
+
"""Load a map builder configuration from the maps directory."""
|
|
17
|
+
normalized = map_name
|
|
18
|
+
if normalized.startswith("evals/"):
|
|
19
|
+
normalized = f"diagnostic_evals/{normalized.split('/', 1)[1]}"
|
|
20
|
+
map_path = MAPS_DIR / normalized
|
|
21
|
+
if not map_path.exists():
|
|
22
|
+
raise FileNotFoundError(f"Map not found: {map_path}")
|
|
23
|
+
return MapGen.Config(
|
|
24
|
+
instance=MapBuilderConfig.from_uri(str(map_path)),
|
|
25
|
+
instances=1, # Force single instance - use spawn points from ASCII map directly
|
|
26
|
+
fixed_spawn_order=False,
|
|
27
|
+
instance_border_width=0, # Don't add border - maps already have borders built in
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
TRAINING_FACILITY = CoGameSite(
|
|
12
32
|
name="training_facility",
|
|
13
33
|
description="COG Training Facility. Basic training facility with open spaces and no obstacles.",
|
|
14
34
|
map_builder=MapGen.Config(
|
|
@@ -25,6 +45,7 @@ TRAINING_FACILITY = Site(
|
|
|
25
45
|
"silicon_extractor",
|
|
26
46
|
],
|
|
27
47
|
cross_bundle="none",
|
|
48
|
+
junction_object="junction",
|
|
28
49
|
)
|
|
29
50
|
),
|
|
30
51
|
),
|
|
@@ -32,7 +53,7 @@ TRAINING_FACILITY = Site(
|
|
|
32
53
|
max_cogs=4,
|
|
33
54
|
)
|
|
34
55
|
|
|
35
|
-
HELLO_WORLD =
|
|
56
|
+
HELLO_WORLD = CoGameSite(
|
|
36
57
|
name="hello_world",
|
|
37
58
|
description="Welcome to space.",
|
|
38
59
|
map_builder=MapGen.Config(width=100, height=100, instance=MachinaArena.Config(spawn_count=20)),
|
|
@@ -40,7 +61,7 @@ HELLO_WORLD = Site(
|
|
|
40
61
|
max_cogs=20,
|
|
41
62
|
)
|
|
42
63
|
|
|
43
|
-
MACHINA_1 =
|
|
64
|
+
MACHINA_1 = CoGameSite(
|
|
44
65
|
name="machina_1",
|
|
45
66
|
description="Your first mission. Collect resources and assemble HEARTs.",
|
|
46
67
|
map_builder=MapGen.Config(width=88, height=88, instance=SequentialMachinaArena.Config(spawn_count=20)),
|
|
@@ -54,6 +75,7 @@ def _cogsguard_hub_config() -> BaseHubConfig:
|
|
|
54
75
|
corner_bundle="extractors",
|
|
55
76
|
cross_bundle="none",
|
|
56
77
|
cross_distance=7,
|
|
78
|
+
junction_object="junction",
|
|
57
79
|
stations=[
|
|
58
80
|
"aligner_station",
|
|
59
81
|
"scrambler_station",
|
|
@@ -66,7 +88,7 @@ def _cogsguard_hub_config() -> BaseHubConfig:
|
|
|
66
88
|
|
|
67
89
|
# Evals site used by diagnostic evaluation missions
|
|
68
90
|
# Note: Individual diagnostic missions override this with their own specific maps
|
|
69
|
-
EVALS =
|
|
91
|
+
EVALS = CoGameSite(
|
|
70
92
|
name="evals",
|
|
71
93
|
description="Diagnostic evaluation arenas.",
|
|
72
94
|
map_builder=get_map("diagnostic_evals/diagnostic_radial.map"), # Default map (rarely used)
|
|
@@ -75,7 +97,7 @@ EVALS = Site(
|
|
|
75
97
|
)
|
|
76
98
|
|
|
77
99
|
|
|
78
|
-
def make_cogsguard_arena_site(num_agents: int = 10) ->
|
|
100
|
+
def make_cogsguard_arena_site(num_agents: int = 10) -> CoGameSite:
|
|
79
101
|
"""Create a CogsGuard arena site with configurable agent count."""
|
|
80
102
|
map_builder = MapGen.Config(
|
|
81
103
|
width=50,
|
|
@@ -86,7 +108,7 @@ def make_cogsguard_arena_site(num_agents: int = 10) -> Site:
|
|
|
86
108
|
hub=_cogsguard_hub_config(),
|
|
87
109
|
),
|
|
88
110
|
)
|
|
89
|
-
return
|
|
111
|
+
return CoGameSite(
|
|
90
112
|
name="cogsguard_arena",
|
|
91
113
|
description="CogsGuard arena map",
|
|
92
114
|
map_builder=map_builder,
|
|
@@ -111,9 +133,9 @@ def _build_cogsguard_machina1_map_builder(spawn_count: int) -> MapGenConfig:
|
|
|
111
133
|
)
|
|
112
134
|
|
|
113
135
|
|
|
114
|
-
def make_cogsguard_machina1_site(num_agents: int = 10) ->
|
|
136
|
+
def make_cogsguard_machina1_site(num_agents: int = 10) -> CoGameSite:
|
|
115
137
|
"""Create a CogsGuard Machina1 site with configurable agent count."""
|
|
116
|
-
return
|
|
138
|
+
return CoGameSite(
|
|
117
139
|
name="cogsguard_machina_1",
|
|
118
140
|
description="CogsGuard Machina1 layout with gear stations.",
|
|
119
141
|
map_builder=_build_cogsguard_machina1_map_builder(num_agents),
|
|
@@ -123,7 +145,7 @@ def make_cogsguard_machina1_site(num_agents: int = 10) -> Site:
|
|
|
123
145
|
|
|
124
146
|
|
|
125
147
|
# Default CogsGuard Machina1 site with flexible agent count
|
|
126
|
-
COGSGUARD_MACHINA_1 =
|
|
148
|
+
COGSGUARD_MACHINA_1 = CoGameSite(
|
|
127
149
|
name="cogsguard_machina_1",
|
|
128
150
|
description="CogsGuard Machina1 layout with gear stations.",
|
|
129
151
|
map_builder=_build_cogsguard_machina1_map_builder(20),
|
|
@@ -132,7 +154,7 @@ COGSGUARD_MACHINA_1 = Site(
|
|
|
132
154
|
)
|
|
133
155
|
|
|
134
156
|
# Default CogsGuard arena site with flexible agent count
|
|
135
|
-
COGSGUARD_ARENA =
|
|
157
|
+
COGSGUARD_ARENA = CoGameSite(
|
|
136
158
|
name="cogsguard_arena",
|
|
137
159
|
description="CogsGuard arena - compact training map with gear stations.",
|
|
138
160
|
map_builder=MapGen.Config(
|
|
@@ -149,20 +171,8 @@ COGSGUARD_ARENA = Site(
|
|
|
149
171
|
)
|
|
150
172
|
|
|
151
173
|
|
|
152
|
-
# Feature flag: Set to True to include legacy (pre-CogsGuard) sites in the CLI.
|
|
153
|
-
# To enable, add TRAINING_FACILITY, HELLO_WORLD, MACHINA_1 to SITES below.
|
|
154
|
-
# Also set _INCLUDE_LEGACY_MISSIONS = True in missions.py.
|
|
155
|
-
_INCLUDE_LEGACY_SITES = False
|
|
156
|
-
|
|
157
|
-
_LEGACY_SITES = [
|
|
158
|
-
TRAINING_FACILITY,
|
|
159
|
-
HELLO_WORLD,
|
|
160
|
-
MACHINA_1,
|
|
161
|
-
]
|
|
162
|
-
|
|
163
174
|
SITES = [
|
|
164
175
|
COGSGUARD_MACHINA_1,
|
|
165
176
|
COGSGUARD_ARENA,
|
|
166
177
|
EVALS,
|
|
167
|
-
*(_LEGACY_SITES if _INCLUDE_LEGACY_SITES else []),
|
|
168
178
|
]
|