Spaces:
Running
Running
Scenario brainstorm + 2 runnable economy packs
Browse filesSCENARIO_BRAINSTORM.md: 13 scenario ideas + the two requested economy
families spec'd, with precise engine-prereq specs. Key finding:
harvest income NOT runnable today (no 'mine' in Python actor whitelist,
no .oramap embeds ore tiles, silo/resource_capacity inert) — so the
shipped economy packs are fixed-budget spend/allocation tests; full
harvest+silo versions are gated on S0 (resource seeding) + S1 (storage
modeling), specced in the doc.
packs/economy-time-box.yaml, economy-investment.yaml: validate OK and
run on the engine (parametrized gate, 15/15). Full bench suite green.
SCENARIO_BRAINSTORM.md
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# OpenRA-Bench — Scenario Brainstorm & Economy Family Spec
|
| 2 |
+
|
| 3 |
+
Design document. No engine or existing-pack changes. Two runnable
|
| 4 |
+
economy packs were drafted and validate OK (see end).
|
| 5 |
+
|
| 6 |
+
All win conditions below use ONLY leaves/composites that exist in
|
| 7 |
+
`win_conditions.py`: `explored_pct_gte, enemies_discovered_gte,
|
| 8 |
+
buildings_discovered_gte, units_killed_gte, units_lost_lte,
|
| 9 |
+
within_ticks, after_ticks, reach_region, all_units_in_region,
|
| 10 |
+
own_units_gte, cash_gte, harvesters_gte, power_surplus_gte,
|
| 11 |
+
has_building, buildings_owned_gte, building_total_gte,
|
| 12 |
+
building_count_gte{type,n}, building_in_region{type?,x,y,radius,count}`;
|
| 13 |
+
composites `all_of / any_of / not`.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Verified ground-truth constraints (this drove the design)
|
| 18 |
+
|
| 19 |
+
1. **No schema-valid ore source.** The Rust engine seeds an ore patch
|
| 20 |
+
in a ~4-cell radius around any actor of type `mine`
|
| 21 |
+
(`openra-sim/src/world.rs` ~L4014, `map_actor.actor_type == "mine"`
|
| 22 |
+
at ~L3908). **But** the Python `ScenarioDefinition` actor whitelist
|
| 23 |
+
(`openra_rl_training.scenario.VALID_ACTOR_TYPES`) has **no `mine` /
|
| 24 |
+
`gmine`**, so a pack that spawns one fails validation. The 5
|
| 25 |
+
`.oramap` files (`map.yaml` inspected) embed **no resource tiles**
|
| 26 |
+
either — only `mpspawn` actors.
|
| 27 |
+
⇒ **Harvest income is 0 in any runnable pack today.** `harv` + `proc`
|
| 28 |
+
spawn fine but find no ore. `cash_gte` is only satisfiable from
|
| 29 |
+
`starting_cash`, and `harvesters_gte` only counts the auto-spawned
|
| 30 |
+
harvester (it never earns).
|
| 31 |
+
2. **`silo` is schema-valid but inert.** `silo` is in
|
| 32 |
+
`VALID_ACTOR_TYPES`, but `PlayerResources.resource_capacity` is
|
| 33 |
+
hardcoded `0` (`openra-sim/src/traits/mod.rs:76,172`,
|
| 34 |
+
`world.rs:3609`) and the deposit path converts ore straight to cash
|
| 35 |
+
ignoring capacity (`world.rs:1467-1473`). Building silos has **no
|
| 36 |
+
economic effect**.
|
| 37 |
+
3. **`starting_cash` works** (per-level / pack-wide, schema confirmed),
|
| 38 |
+
build/train with tech-tree prerequisites works, `proc` auto-spawns
|
| 39 |
+
one `harv` on creation (`world.rs:1154`).
|
| 40 |
+
4. Only `rush-hour-arena` is Rust-loadable today (CONTRIBUTING §5);
|
| 41 |
+
the four `singles-*` maps are schema-valid but Phase-3-gated.
|
| 42 |
+
|
| 43 |
+
**Design consequence:** runnable economy scenarios test the
|
| 44 |
+
**spend / allocation** decision over a fixed budget (the part the lead
|
| 45 |
+
identified as the real test). Harvest-throughput and silo-storage
|
| 46 |
+
variants are fully specced but tagged engine-prereq.
|
| 47 |
+
|
| 48 |
+
---
|
| 49 |
+
|
| 50 |
+
# 1. Requested family — Economy-Time-Box (RUNNABLE TODAY)
|
| 51 |
+
|
| 52 |
+
**Pack:** `packs/economy-time-box.yaml` — validates **OK**.
|
| 53 |
+
**Capability:** reasoning.
|
| 54 |
+
**Decision:** within a fixed tick budget, convert a fixed cash budget
|
| 55 |
+
into BOTH deployed units AND a standing economy; idle cash and
|
| 56 |
+
all-in-on-units both fail.
|
| 57 |
+
|
| 58 |
+
real_world_meaning — Time-bounded capital deployment: a finite,
|
| 59 |
+
non-replenishing budget must become mission capability *and* persistent
|
| 60 |
+
infrastructure before a hard deadline.
|
| 61 |
+
robotics_analogue — A field robot on a finite energy budget scheduling
|
| 62 |
+
expenditure between mission work and standing up persistent
|
| 63 |
+
infrastructure before a deadline.
|
| 64 |
+
|
| 65 |
+
| Level | starting_cash | win_condition (real grammar) | scaling axis |
|
| 66 |
+
|---|---|---|---|
|
| 67 |
+
| easy | 4000 | `all_of[own_units_gte:4, building_total_gte:4, within_ticks:22000]` | loose clock & budget |
|
| 68 |
+
| medium | 2400 | `all_of[own_units_gte:5, has_building:tent, building_total_gte:4, within_ticks:16000]` | adds tech-dep building, tighter |
|
| 69 |
+
| hard | 1500 | `all_of[own_units_gte:6, building_total_gte:5, units_lost_lte:0, within_ticks:12000]` | lean budget, short clock, attrition cap |
|
| 70 |
+
|
| 71 |
+
Difficulty comes from the decision getting harder (less budget slack,
|
| 72 |
+
a tech-dependency constraint, an attrition cap + short clock), not
|
| 73 |
+
bigger target numbers. Predicates: `own_units_gte`, `building_total_gte`,
|
| 74 |
+
`has_building`, `units_lost_lte`, `within_ticks`. Commands: `build`,
|
| 75 |
+
`place_building`, `move_units`, `deploy`, `stop`. Map: `rush-hour-arena`.
|
| 76 |
+
|
| 77 |
+
**Engine status: runnable now.**
|
| 78 |
+
|
| 79 |
+
### Follow-up (leaderboard scoring, not a predicate today)
|
| 80 |
+
A *final-economy-value* score = `cash + Σ asset_value(owned units &
|
| 81 |
+
buildings)` at the deadline would reward "spent it well" beyond the
|
| 82 |
+
binary `cash_gte`. No such predicate exists; propose it as a scoring /
|
| 83 |
+
leaderboard metric computed from the render state at episode end (sum
|
| 84 |
+
buildable costs of `own_buildings` + `units_summary`, add `signals.cash`).
|
| 85 |
+
Do **not** add it as a win leaf — pass/fail stays in the grammar above.
|
| 86 |
+
|
| 87 |
+
### Harvest-income variant — **needs S0 + S1** (see §Engine-prereqs)
|
| 88 |
+
Same shape but income comes from harvesting and `cash_gte` rises over
|
| 89 |
+
time: `all_of[cash_gte:N, own_units_gte:K, harvesters_gte:1,
|
| 90 |
+
within_ticks:T]`. Requires S0 (schema-valid ore source so harvesting
|
| 91 |
+
actually earns) — and S1 only if silo storage is part of the test.
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
# 2. Requested family — Economy-Investment (allocation decision)
|
| 96 |
+
|
| 97 |
+
**Pack:** `packs/economy-investment.yaml` — validates **OK** (runnable
|
| 98 |
+
variant).
|
| 99 |
+
|
| 100 |
+
real_world_meaning — Capital allocation under one indivisible budget:
|
| 101 |
+
the same cash buys either a *wide* economy (more depot/throughput
|
| 102 |
+
capacity) or a *deep* one (more collectors/force); the budget covers
|
| 103 |
+
exactly one coherent path, so splitting builds neither.
|
| 104 |
+
robotics_analogue — Fleet capital allocation: a fixed budget buying
|
| 105 |
+
either added depot/processing capacity or added collector agents — the
|
| 106 |
+
throughput-vs-collection trade, where indecision yields neither.
|
| 107 |
+
|
| 108 |
+
### (a) Runnable-today variant — RUNNABLE NOW
|
| 109 |
+
Income is the fixed `starting_cash`; the allocation is verified by
|
| 110 |
+
build predicates (no silo, no harvest dependency).
|
| 111 |
+
|
| 112 |
+
| Level | starting_cash | win_condition (real grammar) | path tested |
|
| 113 |
+
|---|---|---|---|
|
| 114 |
+
| easy | 4500 | `all_of[building_count_gte{proc,2}, building_count_gte{powr,2}, within_ticks:22000]` | wide, loose |
|
| 115 |
+
| medium | 3200 | `all_of[building_count_gte{proc,2}, building_count_gte{powr,2}, own_units_gte:3, within_ticks:16000]` | wide + utilisation, tighter |
|
| 116 |
+
| hard | 2600 | `all_of[own_units_gte:6, building_count_gte{proc,1}, units_lost_lte:0, within_ticks:14000]` | deep (force) under lean budget + attrition |
|
| 117 |
+
|
| 118 |
+
Difficulty escalates by removing budget slack so the allocation must be
|
| 119 |
+
committed (a split budget clears no bar), tightening the clock, and
|
| 120 |
+
adding an attrition cap. Predicates: `building_count_gte{type,n}`,
|
| 121 |
+
`own_units_gte`, `units_lost_lte`, `within_ticks`. Commands as above.
|
| 122 |
+
Map `rush-hour-arena`.
|
| 123 |
+
|
| 124 |
+
### (b) Full version — **ENGINE-PREREQ (needs S0 + S1)**
|
| 125 |
+
The faithful test the lead asked for: enough cash for **two refineries
|
| 126 |
+
OR one refinery + extra harvesters**, scored by **harvested cash at the
|
| 127 |
+
deadline**, plus **silos that raise the harvest cap**.
|
| 128 |
+
|
| 129 |
+
- Levels: easy = budget covers either path comfortably (commit to one);
|
| 130 |
+
medium = budget covers exactly one (the bottleneck differs: 2×proc =
|
| 131 |
+
unload throughput, 1×proc+harv = gather rate); hard = lean budget +
|
| 132 |
+
short clock + silo decision (must build `silo` to avoid capping the
|
| 133 |
+
resource pool before a return trip).
|
| 134 |
+
- Win grammar (valid leaves, *meaningful only after S0/S1*):
|
| 135 |
+
`all_of[cash_gte:N, harvesters_gte:H, within_ticks:T]` for the
|
| 136 |
+
allocation; the silo sub-goal is observable as
|
| 137 |
+
`building_count_gte{type:silo,n:K}` but only *matters* after S1.
|
| 138 |
+
- **Engine status: needs S0 (income) + S1 (storage).** Without them the
|
| 139 |
+
two allocations are economically identical (income 0) so the
|
| 140 |
+
scenario is not discriminating — hence variant (a) ships instead.
|
| 141 |
+
|
| 142 |
+
---
|
| 143 |
+
|
| 144 |
+
## Engine-prerequisite specs
|
| 145 |
+
|
| 146 |
+
### S0 — schema-valid ore source (smaller, unblocks all harvest income)
|
| 147 |
+
Today the only ore mechanism is `actor_type == "mine"`, which the
|
| 148 |
+
Python schema rejects. Two non-engine-code options the project could
|
| 149 |
+
take (documented here, not implemented):
|
| 150 |
+
- Add `mine`/`gmine` to `VALID_ACTOR_TYPES` in
|
| 151 |
+
`openra_rl_training/scenario.py` (one list entry; the Rust seed loop
|
| 152 |
+
at `world.rs:4014` already handles it), **or**
|
| 153 |
+
- Add a `resource_fields: [{x,y,radius,density}]` field to
|
| 154 |
+
`ScenarioDefinition` plumbed to `terrain.set_resource(...)`
|
| 155 |
+
(`openra-sim/src/terrain.rs:193`) at world init.
|
| 156 |
+
Either makes harvest income real and unblocks the §1 harvest variant
|
| 157 |
+
and §2(b) allocation scoring (without silos).
|
| 158 |
+
|
| 159 |
+
### S1 — silo / resource-storage modeling (the part to flag)
|
| 160 |
+
Goal: harvested resource enters a **capped pool**; cash is realised
|
| 161 |
+
from the pool gradually (or on cap pressure), and `silo` buildings
|
| 162 |
+
raise the cap. Precise change (Rust):
|
| 163 |
+
|
| 164 |
+
1. **`openra-sim/src/traits/mod.rs`** — `TraitState::PlayerResources {
|
| 165 |
+
cash, resources, resource_capacity }` already has the fields; stop
|
| 166 |
+
hardcoding `resource_capacity: 0` at the two constructor sites
|
| 167 |
+
(`mod.rs:172`, `world.rs:3609`). Give players a small base capacity
|
| 168 |
+
(e.g. from `fact`/`proc`).
|
| 169 |
+
2. **`openra-sim/src/world.rs` deposit path (~L1467-1473, `Unloading`
|
| 170 |
+
arm of `tick_harvesters`)** — instead of `player.set_cash(current +
|
| 171 |
+
value)`, add to `PlayerResources.resources`, clamped to
|
| 172 |
+
`resource_capacity`; overflow is lost (matches OpenRA). Add a
|
| 173 |
+
per-tick drain that converts `resources → cash` at a fixed rate
|
| 174 |
+
(the realisation of stored ore).
|
| 175 |
+
3. **Silo capacity contribution** — when an actor of type `silo`
|
| 176 |
+
(and `proc`, in real OpenRA) becomes owned/active, add its
|
| 177 |
+
`Storage` amount to the owning player's `resource_capacity`;
|
| 178 |
+
subtract on loss. Implement as a recompute over owned buildings in
|
| 179 |
+
the building add/remove path (mirror how `PowerManager`
|
| 180 |
+
provided/drained is recomputed), reading a per-building storage
|
| 181 |
+
constant (silo ≈ 3000, proc ≈ 2000 in RA defaults).
|
| 182 |
+
4. **(optional) win/score** — no `resources_gte` predicate exists;
|
| 183 |
+
either add one to `_PREDICATES` in `win_conditions.py` (one entry,
|
| 184 |
+
pure: `c.signals.resources >= int(v)`) and expose `resources` on
|
| 185 |
+
`EpisodeSignals`, or keep pass/fail on `cash_gte` and surface
|
| 186 |
+
stored-value only in the leaderboard score.
|
| 187 |
+
|
| 188 |
+
With S1, building silos genuinely changes optimal play (don't cap;
|
| 189 |
+
don't over-invest in storage you can't fill), making §2(b)
|
| 190 |
+
discriminating.
|
| 191 |
+
|
| 192 |
+
---
|
| 193 |
+
|
| 194 |
+
## 3. Broader brainstorm — 13 scenario ideas across capabilities
|
| 195 |
+
|
| 196 |
+
Each: capability · real_world_meaning / robotics_analogue · win
|
| 197 |
+
(real grammar) · predicates+commands · map · engine status.
|
| 198 |
+
None duplicate the existing 13 packs.
|
| 199 |
+
|
| 200 |
+
### Perception
|
| 201 |
+
|
| 202 |
+
**P1 — Resource-Patch Discovery Under Fog**
|
| 203 |
+
- perception. RWM: locating *where* to forage before committing
|
| 204 |
+
collectors is the real foraging problem, not the path to a known
|
| 205 |
+
patch. RA: SLAM-time frontier selection for a resource map.
|
| 206 |
+
- win: `all_of[explored_pct_gte:55, within_ticks:9000]`
|
| 207 |
+
- uses `explored_pct_gte`,`within_ticks`; `move_units`,`observe`,`stop`.
|
| 208 |
+
Map `rush-hour-arena`.
|
| 209 |
+
- engine status: runnable now.
|
| 210 |
+
|
| 211 |
+
**P2 — Count-the-Threats Before Acting**
|
| 212 |
+
- perception. RWM: estimating force size from partial sightings before
|
| 213 |
+
engaging is a recon-quality problem distinct from combat. RA:
|
| 214 |
+
multi-target detection/enumeration under occlusion.
|
| 215 |
+
- win: `all_of[enemies_discovered_gte:N, units_lost_lte:0,
|
| 216 |
+
within_ticks:T]` (levels raise N, add decoy idle units, tighten T).
|
| 217 |
+
- uses `enemies_discovered_gte`,`units_lost_lte`,`within_ticks`;
|
| 218 |
+
`move_units`,`observe`. Map `rush-hour-arena`.
|
| 219 |
+
- engine status: runnable now.
|
| 220 |
+
|
| 221 |
+
**P3 — Identify the Production Building (signature ID)**
|
| 222 |
+
- perception. RWM: classifying an installation by observable signature
|
| 223 |
+
before acting on it. RA: semantic recognition of a target structure
|
| 224 |
+
from sensor returns.
|
| 225 |
+
- win: `all_of[buildings_discovered_gte:1, within_ticks:T]`; hard adds
|
| 226 |
+
decoy buildings + tighter clock.
|
| 227 |
+
- uses `buildings_discovered_gte`,`within_ticks`;
|
| 228 |
+
`move_units`,`observe`. Map `rush-hour-arena`.
|
| 229 |
+
- engine status: runnable now.
|
| 230 |
+
|
| 231 |
+
### Reasoning
|
| 232 |
+
|
| 233 |
+
**R1 — Tech-Tree Critical Path**
|
| 234 |
+
- reasoning. RWM: ordering prerequisite-coupled tasks (B needs power
|
| 235 |
+
needs ...) to hit a deadline is scheduling, not building. RA:
|
| 236 |
+
task-graph scheduling with hard precedence + a makespan deadline.
|
| 237 |
+
- win: `all_of[has_building:tent, building_total_gte:4,
|
| 238 |
+
power_surplus_gte:0, within_ticks:T]`; levels shorten T, raise depth.
|
| 239 |
+
- uses `has_building`,`building_total_gte`,`power_surplus_gte`,
|
| 240 |
+
`within_ticks`; `build`,`place_building`,`deploy`. `rush-hour-arena`.
|
| 241 |
+
- engine status: runnable now.
|
| 242 |
+
|
| 243 |
+
**R2 — Power-Budget Brownout Avoidance**
|
| 244 |
+
- reasoning. RWM: keeping a power budget non-negative while expanding —
|
| 245 |
+
an online resource-constraint problem. RA: a robot keeping net power
|
| 246 |
+
≥ 0 while bringing subsystems online.
|
| 247 |
+
- win: `all_of[power_surplus_gte:0, building_total_gte:N,
|
| 248 |
+
within_ticks:T]`; hard raises N with scarce power slack.
|
| 249 |
+
- uses `power_surplus_gte`,`building_total_gte`,`within_ticks`;
|
| 250 |
+
`build`,`place_building`,`power_down`. `rush-hour-arena`.
|
| 251 |
+
- engine status: runnable now.
|
| 252 |
+
|
| 253 |
+
**R3 — Defensive-Direction Commitment**
|
| 254 |
+
- reasoning. RWM: committing limited defenses to the *right* approach
|
| 255 |
+
under directional uncertainty. RA: sensor/effector placement toward
|
| 256 |
+
the most likely intrusion bearing.
|
| 257 |
+
- win: `all_of[building_in_region{type:pbox,x:40,y:20,radius:9,
|
| 258 |
+
count:2}, within_ticks:T]`; levels move/duplicate the threat axis.
|
| 259 |
+
- uses `building_in_region`,`within_ticks`;
|
| 260 |
+
`build`,`place_building`. `rush-hour-arena`.
|
| 261 |
+
- engine status: runnable now.
|
| 262 |
+
|
| 263 |
+
**R4 — Economy-Time-Box** (§1) — reasoning — engine status: runnable now.
|
| 264 |
+
|
| 265 |
+
**R5 — Economy-Investment (a)** (§2a) — reasoning — runnable now;
|
| 266 |
+
full (b) **needs S0 + S1**.
|
| 267 |
+
|
| 268 |
+
### Action
|
| 269 |
+
|
| 270 |
+
**A1 — Synchronised Multi-Squad Arrival**
|
| 271 |
+
- action. RWM: executing a plan so dispersed agents *converge*
|
| 272 |
+
simultaneously — coordination/execution, not planning. RA:
|
| 273 |
+
multi-robot rendezvous with a timing constraint.
|
| 274 |
+
- win: `all_of[all_units_in_region{x:90,y:20,radius:6},
|
| 275 |
+
units_lost_lte:0, within_ticks:T]`; levels split start positions
|
| 276 |
+
wider, tighten T.
|
| 277 |
+
- uses `all_units_in_region`,`units_lost_lte`,`within_ticks`;
|
| 278 |
+
`move_units`,`attack_move`,`stop`. `rush-hour-arena`.
|
| 279 |
+
- engine status: runnable now.
|
| 280 |
+
|
| 281 |
+
**A2 — Sequenced Build-then-Relocate**
|
| 282 |
+
- action. RWM: executing an ordered build→deploy→reposition sequence
|
| 283 |
+
without dropping a step under a clock. RA: a fixed manipulation
|
| 284 |
+
sequence (assemble → carry → place) executed to deadline.
|
| 285 |
+
- win: `all_of[building_in_region{x:60,y:20,radius:10,count:2},
|
| 286 |
+
units_lost_lte:1, within_ticks:T]`.
|
| 287 |
+
- uses `building_in_region`,`units_lost_lte`,`within_ticks`;
|
| 288 |
+
`move_units`,`deploy`,`build`,`place_building`. `rush-hour-arena`.
|
| 289 |
+
- engine status: runnable now.
|
| 290 |
+
|
| 291 |
+
**A3 — Harvester Re-tasking Under Interruption**
|
| 292 |
+
- action. RWM: keeping a foraging loop alive by promptly re-tasking
|
| 293 |
+
collectors when the route is disrupted. RA: closed-loop recovery of a
|
| 294 |
+
collection cycle after an interruption.
|
| 295 |
+
- win: `all_of[harvesters_gte:1, cash_gte:N, within_ticks:T]` — only
|
| 296 |
+
meaningful once harvesting earns.
|
| 297 |
+
- uses `harvesters_gte`,`cash_gte`,`within_ticks`;
|
| 298 |
+
`harvest`,`move_units`,`stop`. `rush-hour-arena`.
|
| 299 |
+
- engine status: **needs S0** (no schema-valid ore source today).
|
| 300 |
+
|
| 301 |
+
### Economy / Tech / Multi-objective
|
| 302 |
+
|
| 303 |
+
**E1 — Economy-Time-Box harvest variant** — see §1 — **needs S0**
|
| 304 |
+
(+ S1 if silos are in the test).
|
| 305 |
+
|
| 306 |
+
**E2 — Economy-Investment full** — see §2(b) — **needs S0 + S1**.
|
| 307 |
+
|
| 308 |
+
**M1 — Earn-and-Survive (multi-objective)**
|
| 309 |
+
- reasoning (multi-objective). RWM: holding an income loop *and* a
|
| 310 |
+
defensive constraint simultaneously — competing objectives under one
|
| 311 |
+
budget. RA: a robot foraging while maintaining a safety constraint.
|
| 312 |
+
- win: `all_of[cash_gte:N, units_lost_lte:0, building_total_gte:K,
|
| 313 |
+
within_ticks:T]` (the `cash_gte` arm is real income only post-S0;
|
| 314 |
+
pre-S0 it degenerates to a spend test like §1).
|
| 315 |
+
- uses `cash_gte`,`units_lost_lte`,`building_total_gte`,`within_ticks`;
|
| 316 |
+
`harvest`,`build`,`move_units`. `rush-hour-arena`.
|
| 317 |
+
- engine status: spend-only form runnable now; income form **needs S0**.
|
| 318 |
+
|
| 319 |
+
---
|
| 320 |
+
|
| 321 |
+
## Summary
|
| 322 |
+
|
| 323 |
+
- **Runnable now:** P1, P2, P3, R1, R2, R3, R4 (economy-time-box),
|
| 324 |
+
R5/§2a (economy-investment runnable variant), A1, A2, and the
|
| 325 |
+
spend-only form of M1 — all expressible in the existing grammar on
|
| 326 |
+
`rush-hour-arena`.
|
| 327 |
+
- **Engine-prereq S0** (schema-valid ore source — a one-line
|
| 328 |
+
whitelist add or a `resource_fields` scenario field; the Rust seed
|
| 329 |
+
loop already exists): unblocks any *harvest income* scenario — A3,
|
| 330 |
+
E1, the income form of M1, and the §2(b) allocation scoring.
|
| 331 |
+
- **Engine-prereq S1** (silo storage: stop hardcoding
|
| 332 |
+
`resource_capacity`, route deposits through a capped `resources`
|
| 333 |
+
pool in `tick_harvesters`, recompute capacity from owned
|
| 334 |
+
`silo`/`proc` buildings, optional `resources_gte` predicate):
|
| 335 |
+
required only for the *silo* mechanic in §2(b).
|
| 336 |
+
- **Final-economy-value scoring** (cash + asset value at deadline) is a
|
| 337 |
+
desirable leaderboard metric, NOT a win predicate — there is no such
|
| 338 |
+
leaf and one should not be assumed.
|
| 339 |
+
|
| 340 |
+
### Files written
|
| 341 |
+
- `openra_bench/scenarios/packs/economy-time-box.yaml` — validator: `OK`
|
| 342 |
+
- `openra_bench/scenarios/packs/economy-investment.yaml` — validator: `OK`
|
| 343 |
+
- `SCENARIO_BRAINSTORM.md` (this file)
|
openra_bench/scenarios/packs/economy-investment.yaml
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
meta:
|
| 2 |
+
id: economy-investment
|
| 3 |
+
title: "Economy Investment: Capital Allocation Under One Budget"
|
| 4 |
+
capability: reasoning
|
| 5 |
+
real_world_meaning: >
|
| 6 |
+
A capital-allocation decision under a single indivisible budget:
|
| 7 |
+
the same cash buys EITHER a wide economy (a second refinery plus
|
| 8 |
+
supporting power — depot/throughput capacity) OR a deep one (one
|
| 9 |
+
refinery plus a larger forward force — collection/utilisation). The
|
| 10 |
+
budget covers exactly one coherent path; splitting it builds
|
| 11 |
+
neither. The test is committing to and completing one allocation,
|
| 12 |
+
not the mechanics of either build.
|
| 13 |
+
robotics_analogue: >
|
| 14 |
+
Fleet capital allocation: a fixed budget that buys either added
|
| 15 |
+
depot/processing capacity or added collector/worker agents — the
|
| 16 |
+
classic throughput-versus-collection trade in an autonomous
|
| 17 |
+
foraging fleet, where indecision (a split budget) yields neither.
|
| 18 |
+
author: autonomous-loop
|
| 19 |
+
|
| 20 |
+
# ENGINE NOTE (verified): harvest income is 0 in a runnable pack today
|
| 21 |
+
# (no schema-valid ore source; .oramap files embed no resource tiles;
|
| 22 |
+
# `silo` is schema-valid but `resource_capacity` is hardcoded 0 so
|
| 23 |
+
# silos have no effect). This runnable variant therefore tests the
|
| 24 |
+
# ALLOCATION decision over a fixed `starting_cash`, verified by build
|
| 25 |
+
# predicates. The full harvest-throughput version (2 proc vs 1 proc +
|
| 26 |
+
# extra harv, scored by harvested cash, plus silo storage cap) is
|
| 27 |
+
# specified in SCENARIO_BRAINSTORM.md and gated on engine-prereqs
|
| 28 |
+
# S0 (schema-valid ore source) and S1 (silo storage modeling).
|
| 29 |
+
base_map: rush-hour-arena
|
| 30 |
+
starting_cash: 4500
|
| 31 |
+
|
| 32 |
+
base:
|
| 33 |
+
agent:
|
| 34 |
+
faction: allies
|
| 35 |
+
enemy:
|
| 36 |
+
faction: soviet
|
| 37 |
+
tools:
|
| 38 |
+
- build
|
| 39 |
+
- place_building
|
| 40 |
+
- move_units
|
| 41 |
+
- deploy
|
| 42 |
+
- stop
|
| 43 |
+
planning: true
|
| 44 |
+
termination:
|
| 45 |
+
max_ticks: 40000
|
| 46 |
+
actors:
|
| 47 |
+
- type: fact
|
| 48 |
+
owner: agent
|
| 49 |
+
position: [10, 18]
|
| 50 |
+
- type: powr
|
| 51 |
+
owner: agent
|
| 52 |
+
position: [14, 18]
|
| 53 |
+
- type: proc
|
| 54 |
+
owner: agent
|
| 55 |
+
position: [10, 22]
|
| 56 |
+
- type: barr
|
| 57 |
+
owner: agent
|
| 58 |
+
position: [14, 22]
|
| 59 |
+
- type: e1
|
| 60 |
+
owner: enemy
|
| 61 |
+
position: [118, 34]
|
| 62 |
+
stance: 0
|
| 63 |
+
|
| 64 |
+
levels:
|
| 65 |
+
easy:
|
| 66 |
+
description: >
|
| 67 |
+
Wide-economy path, generous clock: invest the budget into a
|
| 68 |
+
second refinery plus supporting power (added throughput
|
| 69 |
+
capacity). Splitting the budget into scattered units instead
|
| 70 |
+
fails the building bar.
|
| 71 |
+
starting_cash: 4500
|
| 72 |
+
win_condition:
|
| 73 |
+
all_of:
|
| 74 |
+
- building_count_gte: {type: proc, n: 2}
|
| 75 |
+
- building_count_gte: {type: powr, n: 2}
|
| 76 |
+
- within_ticks: 22000
|
| 77 |
+
max_turns: 70
|
| 78 |
+
medium:
|
| 79 |
+
description: >
|
| 80 |
+
Budget covers exactly one coherent path. The wide-economy
|
| 81 |
+
allocation is scored here (second refinery + power + a small
|
| 82 |
+
utilising force) under a tighter clock; the deep alternative is
|
| 83 |
+
the hard level.
|
| 84 |
+
starting_cash: 3200
|
| 85 |
+
win_condition:
|
| 86 |
+
all_of:
|
| 87 |
+
- building_count_gte: {type: proc, n: 2}
|
| 88 |
+
- building_count_gte: {type: powr, n: 2}
|
| 89 |
+
- own_units_gte: 3
|
| 90 |
+
- within_ticks: 16000
|
| 91 |
+
max_turns: 80
|
| 92 |
+
hard:
|
| 93 |
+
description: >
|
| 94 |
+
Lean budget forces the DEEP allocation: keep the single refinery
|
| 95 |
+
and instead convert the budget into a larger forward force under
|
| 96 |
+
a short clock with an attrition cap. Only a committed (unsplit)
|
| 97 |
+
allocation clears the bar in time.
|
| 98 |
+
starting_cash: 2600
|
| 99 |
+
win_condition:
|
| 100 |
+
all_of:
|
| 101 |
+
- own_units_gte: 6
|
| 102 |
+
- building_count_gte: {type: proc, n: 1}
|
| 103 |
+
- units_lost_lte: 0
|
| 104 |
+
- within_ticks: 14000
|
| 105 |
+
max_turns: 90
|
openra_bench/scenarios/packs/economy-time-box.yaml
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
meta:
|
| 2 |
+
id: economy-time-box
|
| 3 |
+
title: "Economy Time-Box: Spend a Fixed Budget Well Under a Clock"
|
| 4 |
+
capability: reasoning
|
| 5 |
+
real_world_meaning: >
|
| 6 |
+
Time-bounded capital deployment: a fixed budget must be converted
|
| 7 |
+
into deployed capability AND a standing economy before a hard tick
|
| 8 |
+
deadline. Cash left unspent at the deadline is wasted; spending it
|
| 9 |
+
all on units leaves no production economy; the decision is the
|
| 10 |
+
spend schedule and the unit/structure mix, not any single build.
|
| 11 |
+
robotics_analogue: >
|
| 12 |
+
A field robot with a finite, non-replenishing energy budget that
|
| 13 |
+
must both perform mission work and stand up persistent
|
| 14 |
+
infrastructure before a deadline — scheduling expenditure so the
|
| 15 |
+
objective is met without exhausting the budget prematurely.
|
| 16 |
+
author: autonomous-loop
|
| 17 |
+
|
| 18 |
+
# ENGINE NOTE (verified): no schema-valid actor seeds ore (the Python
|
| 19 |
+
# ScenarioDefinition whitelist has no `mine`/`gmine`; the 5 .oramap
|
| 20 |
+
# files embed no resource tiles), so harvest income is 0 in a runnable
|
| 21 |
+
# pack today. Income here is therefore the fixed `starting_cash`; the
|
| 22 |
+
# tested decision is the SPEND schedule. A harvest-income variant is
|
| 23 |
+
# specified in SCENARIO_BRAINSTORM.md, gated on engine-prereq S0
|
| 24 |
+
# (schema-valid ore source) + S1 (storage).
|
| 25 |
+
base_map: rush-hour-arena
|
| 26 |
+
starting_cash: 4000
|
| 27 |
+
|
| 28 |
+
base:
|
| 29 |
+
agent:
|
| 30 |
+
faction: allies
|
| 31 |
+
enemy:
|
| 32 |
+
faction: soviet
|
| 33 |
+
tools:
|
| 34 |
+
- build
|
| 35 |
+
- place_building
|
| 36 |
+
- move_units
|
| 37 |
+
- deploy
|
| 38 |
+
- stop
|
| 39 |
+
planning: true
|
| 40 |
+
termination:
|
| 41 |
+
max_ticks: 40000
|
| 42 |
+
actors:
|
| 43 |
+
- type: fact
|
| 44 |
+
owner: agent
|
| 45 |
+
position: [10, 18]
|
| 46 |
+
- type: powr
|
| 47 |
+
owner: agent
|
| 48 |
+
position: [14, 18]
|
| 49 |
+
- type: barr
|
| 50 |
+
owner: agent
|
| 51 |
+
position: [10, 22]
|
| 52 |
+
- type: e1
|
| 53 |
+
owner: enemy
|
| 54 |
+
position: [118, 34]
|
| 55 |
+
stance: 0
|
| 56 |
+
|
| 57 |
+
levels:
|
| 58 |
+
easy:
|
| 59 |
+
description: >
|
| 60 |
+
Generous budget and clock. Field a small force and keep an
|
| 61 |
+
economy building standing: the only failure is leaving the
|
| 62 |
+
budget idle or spending it down to nothing.
|
| 63 |
+
starting_cash: 4000
|
| 64 |
+
win_condition:
|
| 65 |
+
all_of:
|
| 66 |
+
- own_units_gte: 4
|
| 67 |
+
- building_total_gte: 4
|
| 68 |
+
- within_ticks: 22000
|
| 69 |
+
max_turns: 60
|
| 70 |
+
medium:
|
| 71 |
+
description: >
|
| 72 |
+
Tighter budget and clock: the spend must start promptly and the
|
| 73 |
+
mix must cover both fielded units and a power-dependent
|
| 74 |
+
structure within the deadline.
|
| 75 |
+
starting_cash: 2400
|
| 76 |
+
win_condition:
|
| 77 |
+
all_of:
|
| 78 |
+
- own_units_gte: 5
|
| 79 |
+
- has_building: tent
|
| 80 |
+
- building_total_gte: 4
|
| 81 |
+
- within_ticks: 16000
|
| 82 |
+
max_turns: 70
|
| 83 |
+
hard:
|
| 84 |
+
description: >
|
| 85 |
+
Lean budget, short clock, attrition cap: every credit and tick
|
| 86 |
+
must convert to fielded force plus a standing economy while
|
| 87 |
+
losing nothing.
|
| 88 |
+
starting_cash: 1500
|
| 89 |
+
win_condition:
|
| 90 |
+
all_of:
|
| 91 |
+
- own_units_gte: 6
|
| 92 |
+
- building_total_gte: 5
|
| 93 |
+
- units_lost_lte: 0
|
| 94 |
+
- within_ticks: 12000
|
| 95 |
+
max_turns: 80
|