agent-econ-quant commited on
Commit
01e4023
·
1 Parent(s): 30c7fcc

feat(scenario): econ-quantitative-vs-qualitative-spend — mass vs elite composition (SC2 / military quantity-vs-quality doctrine anchor)

Browse files
openra_bench/scenarios/packs/econ-quantitative-vs-qualitative-spend.yaml ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # econ-quantitative-vs-qualitative-spend
2
+ #
3
+ # Quantity vs Quality under a fixed budget — the SC2 "mass cheap" vs
4
+ # "few elite" composition decision; military doctrine "quantity has a
5
+ # quality of its own" tension; OR unit-composition optimisation.
6
+ #
7
+ # Real-world: industrial mass-production vs craftsmanship; SC2 zergling
8
+ # swarm vs carrier doctrine; military mass conscription vs elite
9
+ # professional formations.
10
+ #
11
+ # Pre-placed (per spec): agent fact + barr (infantry trainer) + weap
12
+ # (vehicle trainer) + 2 starter units. The barr+weap pair makes BOTH
13
+ # the mass-cheap (e1 @ $100) and elite (3tnk @ $950) compositions
14
+ # buildable from turn 1 — the decision is *composition*, not tech.
15
+ #
16
+ # Discrimination on EASY / MEDIUM (single garrison, both comps work):
17
+ # • stall (only observe): never reaches the kill bar → after_ticks
18
+ # LOSS.
19
+ # • mixed-composition / brittle spend (1 tank + 4 e1): neither bar is
20
+ # comfortably met under the loss cap on the medium garrison — the
21
+ # small mix bleeds units and underdelivers DPS → LOSS.
22
+ # • intended commit-cheap (8× e1 swarm): swarm DPS overwhelms the
23
+ # small garrison, infantry are individually expendable under the
24
+ # loss cap → WIN.
25
+ # • intended commit-elite (3× 3tnk wedge): 3 heavy tanks ($30 DPS,
26
+ # $450 HP each) burn through the same garrison with ≤1 loss → WIN.
27
+ #
28
+ # Discrimination on HARD (composition flips per spawn):
29
+ # • The map carries TWO garrisons placed at fixed (north / south)
30
+ # positions — one anti-INFANTRY (e1 mass + dog + pbox: punishing
31
+ # to a swarm), one anti-VEHICLE (e3 anti-tank mass: punishing to
32
+ # tanks). The agent spawns near ONE of them (spawn_point 0 = north
33
+ # base, spawn_point 1 = south base, round-robined by seed).
34
+ # • The within_ticks budget is too tight to cross the map to engage
35
+ # the OTHER garrison — the agent MUST commit to its local one.
36
+ # • The right composition flips per seed: north spawn faces the
37
+ # anti-INFANTRY garrison ⇒ mass e1 LOSES, elite 3tnk WINS.
38
+ # South spawn faces the anti-VEHICLE garrison ⇒ elite 3tnk
39
+ # LOSES (rocket soldiers shred tanks), mass e1 WINS (rockets
40
+ # overkill cheap rifles, the swarm closes range and overwhelms).
41
+ # • A single memorised "always build tanks" or "always build mass"
42
+ # opening therefore loses on half the seeds — the agent must read
43
+ # the local garrison and counter-pick.
44
+ #
45
+ # Engine guardrails:
46
+ # • Map: rush-hour-arena (128 × 40, playable x in [2..126],
47
+ # y in [2..38]).
48
+ # • Far enemy `fact` at (124,20) prevents engine auto-done when a
49
+ # garrison falls — the kill bar is satisfied on units, not
50
+ # buildings; the fact keeps the episode running through the
51
+ # terminal evaluator frame.
52
+ # • after_ticks fail clauses reachable within max_turns
53
+ # (tick ≤ 93 + 90·(max_turns-1) ⇒ within_ticks 5400 < 5403 at
54
+ # max_turns 60); a staller hits after_ticks 5401 and LOSES, never
55
+ # draws.
56
+ # • Enemy actors do NOT honour spawn_point (CLAUDE.md), so BOTH
57
+ # garrisons place on every seed; only the agent's spawn corner
58
+ # varies. The two garrison cells are far enough apart and the
59
+ # tick budget is tight enough that committing to the wrong
60
+ # corner busts the deadline.
61
+ # • starting_cash funds either composition cleanly with surplus:
62
+ # elite = 3×$950 = $2850; mass = 8×$100 = $800; budget = $4500.
63
+ # A mixed-composition spend (e.g. 1 tank + 5 e1) underdelivers on
64
+ # either axis: not enough DPS to bust the garrison in time, not
65
+ # enough HP to survive the loss cap.
66
+ # • Faction = soviet (so 3tnk + barr are both native to the faction;
67
+ # a barr+weap pair makes both e1 swarm and 3tnk armour buildable
68
+ # from turn 1 without an extra tech step).
69
+
70
+ meta:
71
+ id: econ-quantitative-vs-qualitative-spend
72
+ title: 'Quantity vs Quality — Pick the Right Composition for the Budget'
73
+ capability: reasoning
74
+ real_world_meaning: >
75
+ A fixed cash budget funds either a SWARM of cheap rifle infantry
76
+ (8× e1 @ $100) OR a small ELITE armoured fist (3× 3tnk @ $950).
77
+ Either composition fits the same budget — the decision is which
78
+ is right for the threat the agent must clear. The kill bar AND
79
+ the attrition cap jointly bind: a stall never reaches the bar;
80
+ a mixed mini-spend (1 tank + a handful of rifles) underdelivers
81
+ on DPS and bleeds units past the loss cap; one of the two pure
82
+ compositions cleanly wins per tier. Hard flips the right answer
83
+ per seed — the agent's spawn corner determines which garrison
84
+ is local, and the local garrison's composition determines whether
85
+ mass cheap or few elite is the right counter (anti-vehicle
86
+ garrison ⇒ mass cheap wins, anti-infantry garrison ⇒ elite
87
+ armour wins).
88
+ robotics_analogue: >
89
+ Fleet provisioning under a fixed CAPEX: same budget buys either
90
+ a swarm of cheap general-purpose drones or a handful of expensive
91
+ high-capability robots. The mission profile (debris field vs
92
+ high-value point target; mass surveillance vs precision strike)
93
+ decides which composition is right — and a half-and-half
94
+ procurement satisfies neither requirement.
95
+ benchmark_anchor:
96
+ - "SC2 mass-vs-elite army composition"
97
+ - "industrial mass-production vs craftsmanship"
98
+ - "military doctrine: quantity has a quality of its own"
99
+ - "OR unit-composition optimization under budget"
100
+ author: openra-bench
101
+
102
+ base_map: rush-hour-arena
103
+ starting_cash: 4500
104
+
105
+ base:
106
+ agent: {faction: soviet}
107
+ enemy: {faction: allies}
108
+ tools: [build, place_building, move_units, attack_unit, attack_move, stop]
109
+ planning: true
110
+ termination: {max_ticks: 8000}
111
+ # Pre-placed: agent fact + barr + weap + 2 starter units. The barr
112
+ # enables e1 (infantry trainer); the weap enables 3tnk (vehicle
113
+ # trainer); the two starter e1 give the agent some scouts on turn 1
114
+ # but cannot meet the kill bar alone — production is required.
115
+ actors:
116
+ - {type: fact, owner: agent, position: [10, 20]}
117
+ - {type: barr, owner: agent, position: [14, 18]}
118
+ - {type: weap, owner: agent, position: [14, 22]}
119
+ - {type: e1, owner: agent, position: [12, 20]}
120
+ - {type: e1, owner: agent, position: [12, 21]}
121
+ # Far persistent enemy marker — prevents engine auto-done when the
122
+ # garrison falls so the win/fail evaluator sees the terminal frame.
123
+ - {type: fact, owner: enemy, position: [124, 20]}
124
+
125
+ levels:
126
+ # ── EASY ─────────────────────────────────────────────────────────
127
+ # Bare composition skill: ONE small mixed garrison at centre. EITHER
128
+ # mass-cheap OR elite-armour clears it; the lazy stall LOSES on
129
+ # after_ticks. Loss cap is forgiving (≤5) so the swarm play doesn't
130
+ # need to be careful with individual rifles.
131
+ easy:
132
+ description: >
133
+ Fixed budget $4500. A small enemy garrison (4 rifle infantry e1
134
+ + 2 anti-tank rocket soldiers e3) sits in the centre. Pick a
135
+ composition that fits the budget — either swarm cheap rifles
136
+ (8× e1 @ $100 = $800) OR a small elite armoured fist (3× 3tnk
137
+ @ $950 = $2850). Both compositions can clear this garrison.
138
+ Win when 6 enemy units are killed AND ≤5 of your units are
139
+ lost, before tick 5400. Stalling, building neither, or
140
+ under-producing fails the clock.
141
+ overrides:
142
+ actors:
143
+ - {type: fact, owner: agent, position: [10, 20]}
144
+ - {type: barr, owner: agent, position: [14, 18]}
145
+ - {type: weap, owner: agent, position: [14, 22]}
146
+ - {type: e1, owner: agent, position: [12, 20]}
147
+ - {type: e1, owner: agent, position: [12, 21]}
148
+ # Single centre garrison: 4 e1 + 2 e3, stance:3 (attack
149
+ # anything in range — fires on contact).
150
+ - {type: e1, owner: enemy, position: [70, 18], stance: 3}
151
+ - {type: e1, owner: enemy, position: [70, 19], stance: 3}
152
+ - {type: e1, owner: enemy, position: [70, 21], stance: 3}
153
+ - {type: e1, owner: enemy, position: [70, 22], stance: 3}
154
+ - {type: e3, owner: enemy, position: [72, 19], stance: 3}
155
+ - {type: e3, owner: enemy, position: [72, 21], stance: 3}
156
+ - {type: fact, owner: enemy, position: [124, 20]}
157
+ win_condition:
158
+ all_of:
159
+ - {units_killed_gte: 6}
160
+ - {units_lost_lte: 5}
161
+ - {within_ticks: 5400}
162
+ fail_condition:
163
+ any_of:
164
+ - {after_ticks: 5401}
165
+ - {not: {units_lost_lte: 5}}
166
+ max_turns: 60
167
+
168
+ # ── MEDIUM ───────────────────────────────────────────────────────
169
+ # The pack-spec tier: same garrison, the bar AND the composition
170
+ # jointly bind. Loss cap is 4 — the swarm play can lose half its
171
+ # rifles and still pass; the tank play can lose 1 and still pass.
172
+ # Mixed-composition mini-spends (1 tank + 4 e1, etc.) bleed past
173
+ # the loss cap; pure compositions cleanly clear it. Both pure
174
+ # compositions WIN on this tier — the model's choice is the
175
+ # measured variable.
176
+ medium:
177
+ description: >
178
+ Fixed budget $4500. A small enemy garrison (4 rifle infantry e1
179
+ + 2 anti-tank rocket soldiers e3) sits in the centre. Commit to
180
+ ONE composition that fits the budget — either swarm cheap
181
+ rifles (8× e1 @ $100 = $800) OR a small elite armoured fist
182
+ (3× 3tnk @ $950 = $2850). A mixed mini-spend (one tank plus a
183
+ few rifles) under-delivers on DPS and bleeds units past the
184
+ loss cap. Win when 6 enemy units are killed AND ≤4 of your
185
+ units are lost, before tick 5400. Stalling, mixing, or
186
+ under-producing fails the bar.
187
+ overrides:
188
+ actors:
189
+ - {type: fact, owner: agent, position: [10, 20]}
190
+ - {type: barr, owner: agent, position: [14, 18]}
191
+ - {type: weap, owner: agent, position: [14, 22]}
192
+ - {type: e1, owner: agent, position: [12, 20]}
193
+ - {type: e1, owner: agent, position: [12, 21]}
194
+ # Single centre garrison, mixed (rifle + rocket); same as easy
195
+ # but the loss cap is tighter (≤4) so a brittle mini-spend
196
+ # fails.
197
+ - {type: e1, owner: enemy, position: [70, 18], stance: 3}
198
+ - {type: e1, owner: enemy, position: [70, 19], stance: 3}
199
+ - {type: e1, owner: enemy, position: [70, 21], stance: 3}
200
+ - {type: e1, owner: enemy, position: [70, 22], stance: 3}
201
+ - {type: e3, owner: enemy, position: [72, 19], stance: 3}
202
+ - {type: e3, owner: enemy, position: [72, 21], stance: 3}
203
+ - {type: fact, owner: enemy, position: [124, 20]}
204
+ win_condition:
205
+ all_of:
206
+ - {units_killed_gte: 6}
207
+ - {units_lost_lte: 4}
208
+ - {within_ticks: 5400}
209
+ fail_condition:
210
+ any_of:
211
+ - {after_ticks: 5401}
212
+ - {not: {units_lost_lte: 4}}
213
+ max_turns: 60
214
+
215
+ # ── HARD ─────────────────────────────────────────────────────────
216
+ # +1 axis: enemy composition flips per seed. TWO garrisons place at
217
+ # fixed (north y=10 / south y=30) positions on every seed (enemy
218
+ # actors don't honour spawn_point — CLAUDE.md). The agent's BASE
219
+ # spawn corner is seed-driven via 2 agent spawn_point groups:
220
+ # spawn_point 0 = NORTH base (fact at (10,10)) → faces north
221
+ # anti-INFANTRY garrison locally → swarm cheap LOSES (the
222
+ # anti-infantry mix shreds e1), elite tanks WIN (cheap rifles
223
+ # and the dog can't pierce 3tnk armour).
224
+ # spawn_point 1 = SOUTH base (fact at (10,30)) → faces south
225
+ # anti-VEHICLE garrison locally → elite tanks LOSE (e3 rocket
226
+ # soldiers shred armour), mass cheap e1 WINS (e3 anti-tank
227
+ # rockets overkill individual rifles, the swarm closes range
228
+ # and overwhelms).
229
+ # The within_ticks budget (5400) is tight enough that crossing the
230
+ # map to engage the OTHER garrison busts the deadline — the agent
231
+ # must commit to its local garrison and counter-pick.
232
+ hard:
233
+ description: >
234
+ Fixed budget $4500. TWO enemy garrisons are placed on the map:
235
+ a NORTH garrison (around y=10) and a SOUTH garrison (around
236
+ y=30) with DIFFERENT compositions — one is anti-INFANTRY
237
+ (mass rifles + dog + pillbox: punishing to a cheap swarm);
238
+ one is anti-VEHICLE (mass anti-tank rocket soldiers e3:
239
+ punishing to armour). Your base spawns at the NORTH or SOUTH
240
+ corner (chosen by seed); the tick budget is too tight to
241
+ cross the map and engage the other garrison. Read the
242
+ composition of your LOCAL garrison, then commit the budget
243
+ to the correct counter — swarm cheap rifles (8× e1 = $800)
244
+ vs an anti-vehicle garrison, OR elite armoured fist
245
+ (3× 3tnk = $2850) vs an anti-infantry garrison. A single
246
+ memorised "always tanks" or "always mass" opening loses on
247
+ half the seeds. Win when 6 enemy units are killed AND ≤4 of
248
+ your units are lost, before tick 5400.
249
+ overrides:
250
+ actors:
251
+ # ── AGENT spawn 0 — NORTH base (y=10) ─────────────────────
252
+ - {type: fact, owner: agent, position: [10, 10], spawn_point: 0}
253
+ - {type: barr, owner: agent, position: [14, 8], spawn_point: 0}
254
+ - {type: weap, owner: agent, position: [14, 12], spawn_point: 0}
255
+ - {type: e1, owner: agent, position: [12, 10], spawn_point: 0}
256
+ - {type: e1, owner: agent, position: [12, 11], spawn_point: 0}
257
+ # ── AGENT spawn 1 — SOUTH base (y=30) ─────────────────────
258
+ - {type: fact, owner: agent, position: [10, 30], spawn_point: 1}
259
+ - {type: barr, owner: agent, position: [14, 28], spawn_point: 1}
260
+ - {type: weap, owner: agent, position: [14, 32], spawn_point: 1}
261
+ - {type: e1, owner: agent, position: [12, 30], spawn_point: 1}
262
+ - {type: e1, owner: agent, position: [12, 31], spawn_point: 1}
263
+ # ── NORTH GARRISON — ANTI-INFANTRY (counters mass cheap) ──
264
+ # Wide rifle line + an attack dog (instakills infantry, useless
265
+ # vs armour) + a pillbox (fixed anti-infantry defence). The
266
+ # rifles + dog give 6 living kill-bar targets; the pbox is a
267
+ # building (not in units_killed) but soaks up swarm DPS.
268
+ - {type: e1, owner: enemy, position: [70, 8], stance: 3}
269
+ - {type: e1, owner: enemy, position: [70, 9], stance: 3}
270
+ - {type: e1, owner: enemy, position: [70, 10], stance: 3}
271
+ - {type: e1, owner: enemy, position: [70, 11], stance: 3}
272
+ - {type: e1, owner: enemy, position: [70, 12], stance: 3}
273
+ - {type: dog, owner: enemy, position: [72, 10], stance: 3}
274
+ - {type: pbox, owner: enemy, position: [74, 10]}
275
+ # ── SOUTH GARRISON — ANTI-VEHICLE (counters elite armour) ──
276
+ # Mass rocket soldiers (e3 anti-tank, dps12 vs armour). Cheap
277
+ # rifles in front would absorb the rocket overkill; against a
278
+ # 3-tank fist the rockets stack up DPS and bust the loss cap.
279
+ # Total enemy unit count = 6 (6× e3).
280
+ - {type: e3, owner: enemy, position: [70, 28], stance: 3}
281
+ - {type: e3, owner: enemy, position: [70, 29], stance: 3}
282
+ - {type: e3, owner: enemy, position: [70, 30], stance: 3}
283
+ - {type: e3, owner: enemy, position: [70, 31], stance: 3}
284
+ - {type: e3, owner: enemy, position: [70, 32], stance: 3}
285
+ - {type: e3, owner: enemy, position: [72, 30], stance: 3}
286
+ # Far persistent enemy marker — prevents engine auto-done
287
+ # when the local garrison falls.
288
+ - {type: fact, owner: enemy, position: [124, 20]}
289
+ win_condition:
290
+ all_of:
291
+ - {units_killed_gte: 6}
292
+ - {units_lost_lte: 4}
293
+ - {within_ticks: 5400}
294
+ fail_condition:
295
+ any_of:
296
+ - {after_ticks: 5401}
297
+ - {not: {units_lost_lte: 4}}
298
+ max_turns: 60