Spaces:
Running
Quality drive: schema fix, 5 new/revised packs, 4 engine tests, scenario audit
Browse filesSchema (openra_bench/scenarios/schema.py):
* ScenarioPack gains top-level ore_patches:/water_cells:/water_rect:/
scheduled_events: fields. Without this declaration pydantic
silently DROPPED top-level keys, so easy+medium tiers of
econ-mine-and-grow had empty ore_patches (only hard tier worked
because it re-declared the field in its overrides).
* compile() falls back to pack-level value when the level's
overrides don't restate the field.
Engine-feature test pinning (4 files, all 9 sub-tests pass):
* test_resource_economy.py — ore_patches: materialise + harvest
loop end-to-end (stall LOSS / intended WIN)
* test_engineer_capture.py — Command.capture_actor proc transfer
* test_tanya_c4.py — Command.c4_detonate destroys building
* test_infiltrate.py — spy reveal + thf cash steal
* Field-name corrections (own_units → units_summary,
enemy_buildings → enemy_buildings_summary,
economy.cash → cash) matching the actual RustObsAdapter shape.
* Engineer/Tanya fog-distance fix (proc must be ≤4 cells from
subject so it appears in initial enemy_buildings_summary).
Scenario packs:
* econ-mine-and-grow.yaml — full redesign (auto-spawn
harv + footprint-overlap defect documented; scripted bar holds)
* econ-contested-expansion.yaml — NEW: front-base economy
with patrol harass at contested patch (bar holds × 4 seeds × tiers)
* econ-multi-patch-allocation.yaml — NEW: 4-patch OR allocation
decision (bar holds × tiers)
* econ-second-base-race.yaml — NEW: tempo expansion to
contested centre vs scripted enemy
* econ-harvester-defense-raid.yaml — NEW: harv-preservation
under raid (escort + stance management)
* spec-tanya-c4-strike.yaml — tick budgets recalibrated
(within_ticks 240/360/600, after_ticks +1)
* spec-thief-steal-cash.yaml — starting_cash rebalanced
(1000 floor so per-player cash gives enemy something to steal)
* spec-nuke-strike.yaml — hard tier added, capability
fixed to 'action' (was 'superweapon', not in enum)
* def-bridge-chokepoint.yaml — NEW chokepoint defense
pack using water_cells:; easy tier scripted bar holds, medium/
hard need new BuildingRusher bot (documented in header)
Audit:
* SCENARIO_UNIQUENESS_AUDIT.md — 95.8% packs healthy (181/189
stall LOSS); 3 real defects identified (mid-economy-under-fire,
combat-naval-shore-strike, spec-spy-infiltrate); base-trade
race = 0 packs (biggest capability gap); map mis-bindings on
183/189 packs.
- SCENARIO_UNIQUENESS_AUDIT.md +496 -0
- data/maps/confined-aisle-64x40.oramap +0 -0
- data/maps/expansion-aggro-3-base-greedy-arena.oramap +0 -0
- data/maps/gen-arena-31f6567b.oramap +0 -0
- data/maps/gen-arena-498d46e9.oramap +0 -0
- data/maps/lh-defense-tech-second-base-arena.oramap +0 -0
- data/maps/mcv-deploy-third-base-arena.oramap +0 -0
- data/maps/mfb-base-1-defend-base-2-build-arena.oramap +0 -0
- data/maps/mfb-mirror-base-east-west-arena.oramap +0 -0
- data/maps/mfb-supply-line-corridor-arena.oramap +0 -0
- data/maps/mfb-third-base-against-clock-arena.oramap +0 -0
- data/maps/mfb-two-base-simultaneous-arena.oramap +0 -0
- data/maps/mid-concede-arena.oramap +0 -0
- data/maps/naval-arena-64x40.oramap +0 -0
- data/maps/scout-arena.oramap +0 -0
- openra_bench/agent.py +43 -1
- openra_bench/eval_core.py +96 -0
- openra_bench/full_playback.py +334 -0
- openra_bench/playback_view.py +117 -6
- openra_bench/providers.py +33 -0
- openra_bench/run_eval.py +55 -7
- openra_bench/scenarios/packs/action-multiunit-coordination.yaml +48 -24
- openra_bench/scenarios/packs/action-sequenced-execution.yaml +46 -22
- openra_bench/scenarios/packs/adv-asymmetric-weaker-must-win.yaml +58 -35
- openra_bench/scenarios/packs/adv-rps-counter-pick.yaml +59 -35
- openra_bench/scenarios/packs/adversarial-skirmish.yaml +12 -5
- openra_bench/scenarios/packs/artofwar-decoy-sacrifice.yaml +35 -14
- openra_bench/scenarios/packs/artofwar-indirect-approach.yaml +39 -18
- openra_bench/scenarios/packs/artofwar-lure-the-tiger.yaml +41 -20
- openra_bench/scenarios/packs/artofwar-sequenced-citadel.yaml +14 -6
- openra_bench/scenarios/packs/build-defensive-skirt-corners.yaml +58 -33
- openra_bench/scenarios/packs/build-defensive-tower-cluster.yaml +54 -30
- openra_bench/scenarios/packs/build-defensive-tower-line.yaml +49 -26
- openra_bench/scenarios/packs/build-engineer-rebuild-after-loss.yaml +59 -36
- openra_bench/scenarios/packs/build-power-down-defensive.yaml +49 -25
- openra_bench/scenarios/packs/build-power-online-first.yaml +44 -24
- openra_bench/scenarios/packs/build-production-throughput-multibuilding.yaml +48 -28
- openra_bench/scenarios/packs/build-rally-point-management.yaml +62 -39
- openra_bench/scenarios/packs/build-repair-priority-under-fire.yaml +59 -36
- openra_bench/scenarios/packs/build-sell-and-rebuild-elsewhere.yaml +61 -38
- openra_bench/scenarios/packs/build-sequence-tech-cheapest.yaml +47 -26
- openra_bench/scenarios/packs/build-sequence-tech-fastest.yaml +39 -19
- openra_bench/scenarios/packs/build-sequence-tech-most-resilient.yaml +70 -47
- openra_bench/scenarios/packs/build-tech-skip-decision.yaml +47 -26
- openra_bench/scenarios/packs/building-and-planning.yaml +39 -18
- openra_bench/scenarios/packs/combat-attack-from-behind-fog.yaml +73 -48
- openra_bench/scenarios/packs/combat-bait-counter-attack.yaml +58 -37
- openra_bench/scenarios/packs/combat-divide-and-conquer.yaml +59 -36
- openra_bench/scenarios/packs/combat-flanking-attack.yaml +65 -44
- openra_bench/scenarios/packs/def-bridge-chokepoint.yaml +2046 -0
|
@@ -0,0 +1,496 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Scenario Uniqueness Audit (Phase 2)
|
| 2 |
+
|
| 3 |
+
Read-only audit of `openra_bench/scenarios/packs/*.yaml`. Scope: 212 YAML
|
| 4 |
+
files (excluding `TEMPLATE.yaml`); 23 in-flight `econ-*` packs were
|
| 5 |
+
deliberately skipped (other agents own them), leaving **189 packs probed**.
|
| 6 |
+
|
| 7 |
+
The probe was a stall policy — `Command.observe()` only — run on the
|
| 8 |
+
hard tier, seed=1, of every pack, through the same code path
|
| 9 |
+
(`openra_bench.eval_core.run_level`) the bench evaluator uses. Each
|
| 10 |
+
result is the engine-evaluated outcome (`win` / `loss` / `draw`),
|
| 11 |
+
final game tick, and the static profile read straight from the YAML.
|
| 12 |
+
|
| 13 |
+
Headline numbers
|
| 14 |
+
- 181 / 189 packs (95.8%) — stall LOSSES (healthy: no-cheat bar holds).
|
| 15 |
+
- 3 packs — stall WINS (the no-cheat bar is broken).
|
| 16 |
+
- 3 packs — stall DRAWS (no real LOSS reachable from a stall play).
|
| 17 |
+
- 2 packs — Rust engine panic at `reset(seed=1)` (both
|
| 18 |
+
`adversarial-siege` / `adversarial-skirmish` — already
|
| 19 |
+
`status: quarantine` in-pack so they are NOT in the default eval set,
|
| 20 |
+
but they remain on disk and panic when explicitly invoked).
|
| 21 |
+
|
| 22 |
+
Quarantined packs are still YAML-discoverable and were probed. They are
|
| 23 |
+
flagged `[Q]` in the lists below.
|
| 24 |
+
|
| 25 |
+
---
|
| 26 |
+
|
| 27 |
+
## Section 1 — Defect packs
|
| 28 |
+
|
| 29 |
+
A "defect" here means stall WINS (the lazy bar fell) or stall DRAWS
|
| 30 |
+
(no real reachable LOSS — the timeout collapses to draw degeneracy
|
| 31 |
+
because the fail predicate never trips). Both are explicit violations
|
| 32 |
+
of the "no defect, no cheat" bar in `CLAUDE.md`.
|
| 33 |
+
|
| 34 |
+
### 1A. Stall WINS (3 — bar fell)
|
| 35 |
+
|
| 36 |
+
| Pack | Outcome | Turn | Tick | Diagnosis |
|
| 37 |
+
|---|---|---|---|---|
|
| 38 |
+
| `mid-economy-under-fire` | **WIN** | 11 | 993 | Stall achieves the win predicate without any agent action. Hard win-clause is `economy_value_gte:4000 AND harv≥2 AND units_lost_lte:2`. With the current engine, the 3 starter harvesters auto-harvest (no `harvest` command needed — they begin in `harvest` mode), the perimeter 1tnks auto-fire and kill the lone raider 1tnk, and EV trips 4000 by tick ~993 with zero losses. The pack header says "Stall (only observe)… harvs never harvest → EV stays at 0 → LOSS." That is no longer true under the current engine — harvs in `harvest` mode work without re-issued orders. **Fix**: either remove the harvesters from the starting placement (require the model to issue `Command.harvest`) or replace the `1tnk` raider with a stronger raider wave that out-attritions an idle defense ring. |
|
| 39 |
+
| `combat-naval-shore-strike` | **WIN** | 3 | 198 | Stall wins inside 3 turns. The hard tier places two destroyers in the water channel on `stance:2` (Defend), and the entire shore garrison on `stance:0` (HoldFire). The destroyers auto-fire on every garrison unit in range and clear all 5 enemies in <200 ticks; the agent never sends a command. **Fix**: set the destroyers to `stance:0` so the agent must issue an `attack_unit` order; or place the shore garrison just outside the destroyer's auto-target range so the agent must manually fire. The whole capability (target an across-shore target with a ranged unit) collapses because the engine fires automatically. |
|
| 40 |
+
| `def-with-ambush` | (intended) **WIN** | 24 | 1233 | **Not a defect — exempt by design**. CLAUDE.md `§Triage coverage`: "1 pack (`def-with-ambush`) is exempt by design (positional-discipline scenario where do-nothing IS the intended policy)." The capability under test is *hold the ambush position*; the four `stance:2` flanker tanks auto-engage the rusher band when it enters weapon range. Listed here only for completeness — no action required. |
|
| 41 |
+
|
| 42 |
+
### 1B. Stall DRAWS (3 — no LOSS reachable)
|
| 43 |
+
|
| 44 |
+
A draw means the win predicate was never met AND the fail predicate
|
| 45 |
+
never tripped, so the level resolves to `draw` (outcome score 0.5).
|
| 46 |
+
This is a defect because it makes the lazy play indistinguishable
|
| 47 |
+
from a partial / borderline play, and inflates the lazy score by
|
| 48 |
+
treating it as half a win.
|
| 49 |
+
|
| 50 |
+
| Pack | Outcome | Turn | Tick | Diagnosis |
|
| 51 |
+
|---|---|---|---|---|
|
| 52 |
+
| `economy-time-box` [Q] | **DRAW** | 80 | 7203 | Already quarantined in-file (reason: "redundant with economy-force-buildup"). The hard tier has **no `fail_condition` at all** (`fail_condition: None`), so a 12000-tick budget that never produces 6 units / 5 buildings simply times out as draw. This is one of the canonical CLAUDE.md defect classes ("no `fail_condition`, or only triggers on full force-wipe; a stall / preserve / partial outcome silently draws"). Since the pack is quarantined the lazy-bar drift is harmless to the default eval; if the pack is ever un-quarantined, add `fail_condition: {after_ticks: 12001}` plus `{not: own_units_gte: 1}`. |
|
| 53 |
+
| `spec-spy-infiltrate` | **DRAW** | 3 | 273 | Hard tier `fail_condition: {after_ticks: 4001}` — i.e. the only failure mode is the deadline. But the agent's only combat-relevant units are 2 spies (`spy`) and the scenario also places one defender `e1`. With stall, the spies are passive while the engine auto-`done`s at turn 3 (likely because the defender `e1` falls to auto-fire or because all agent combat units are destroyed). The outcome lands as DRAW because the spy-only force is wiped before the within_ticks ever bites. **Fix**: add `{not: own_units_gte: 1}` (or `unit_type_count_gte:{spy, 1}`) to the `fail_condition.any_of` so a spy-wipe is a LOSS, not a draw. Same fix likely needed for `easy` / `medium` (uninspected; consider auditing). |
|
| 54 |
+
| `def-bridge-chokepoint` | (mixed: usually **LOSS** at tick 1623, occasionally **DRAW** in one fresh process) | 18 | 1623 | The first probe (subprocess #1) reported DRAW; three subsequent re-runs from a fresh process consistently reported LOSS (17 losses, fail-clause `not has_building:fact` trips when the procs/fact fall under the rifle assault). This is borderline — the pack is *probably* healthy, but the one-off DRAW observation suggests a possible determinism-edge case (race between the engine auto-`done` and the predicate evaluator). Recommend a 4-seed re-probe (1–4) over a clean Python process to confirm. If the LOSS is stable, no fix required; if the DRAW resurfaces, add `{not: own_units_gte: 1}` to the fail clause. |
|
| 55 |
+
|
| 56 |
+
### 1C. Engine panics at reset (2)
|
| 57 |
+
|
| 58 |
+
| Pack | Status | Error |
|
| 59 |
+
|---|---|---|
|
| 60 |
+
| `adversarial-siege` | `quarantine` (consolidated into `adversarial-duel`) | `pathfinder.rs:175 index out of bounds: len 5120, index 5382` at `env.reset(seed=1)`. The hard tier places actors outside the playable bounds (CLAUDE.md footgun #6) for the chosen spawn. Pack is excluded from default eval; no eval-time impact, but flag the file is still selectable via explicit `--packs`. |
|
| 61 |
+
| `adversarial-skirmish` | `quarantine` (consolidated into `adversarial-duel`) | Same panic at `env.reset`. Same situation as above. |
|
| 62 |
+
|
| 63 |
+
Recommend either deleting these two YAMLs (the consolidation is the
|
| 64 |
+
documented future state) or moving them to `packs/_archived/` so
|
| 65 |
+
`discover_packs` skips them (it already skips `_*` and `TEMPLATE`).
|
| 66 |
+
|
| 67 |
+
---
|
| 68 |
+
|
| 69 |
+
## Section 2 — Duplicate / near-duplicate clusters
|
| 70 |
+
|
| 71 |
+
Methodology: each pack was fingerprinted by
|
| 72 |
+
`(capability, tools, actor_types_sorted, win_predicate_keys_sorted)`.
|
| 73 |
+
Five strict (= all four fields equal) clusters surfaced; a second pass
|
| 74 |
+
relaxed `tools` and `actor_types` to surface near-duplicates with the
|
| 75 |
+
same capability + same win-key set, which surfaced a further ~10
|
| 76 |
+
clusters. Each cluster is judged on the per-pack `real_world_meaning`
|
| 77 |
+
and the `level_description` of the hard tier — if these tell the same
|
| 78 |
+
story, the cluster is genuinely redundant; if not, the predicate-key
|
| 79 |
+
match is coincidental and the packs probe distinct skills.
|
| 80 |
+
|
| 81 |
+
### 2A. Strict duplicates (action required)
|
| 82 |
+
|
| 83 |
+
1. **`adversarial-siege` + `adversarial-skirmish`** — both already
|
| 84 |
+
quarantined as "consolidated into `adversarial-duel`". **Keep:**
|
| 85 |
+
`adversarial-duel`. **Action:** physical removal (delete or
|
| 86 |
+
`_archive`) — they are the only two packs that crash the engine at
|
| 87 |
+
load, so removing them eliminates the crash class entirely.
|
| 88 |
+
|
| 89 |
+
2. **`artofwar-decoy-sacrifice` + `artofwar-lure-the-tiger`** — both
|
| 90 |
+
`capability: reasoning`, both use bot `guard`, identical hard-tier
|
| 91 |
+
actor list `[2tnk,e1,e3,fact,jeep]`, identical win-keys
|
| 92 |
+
`{units_in_region_gte, units_lost_lte, within_ticks}`, both
|
| 93 |
+
described as "main-force reaches an objective by diverting a
|
| 94 |
+
leashed defender." **Keep:** `artofwar-lure-the-tiger` (the more
|
| 95 |
+
doctrinally complete framing — leash mechanic; "the strong
|
| 96 |
+
defender" is the load-bearing pull). **Merge / delete:**
|
| 97 |
+
`artofwar-decoy-sacrifice` — its "spend a decoy unit" angle is
|
| 98 |
+
covered by the `units_lost_lte` clause in the lure pack, which
|
| 99 |
+
already permits a small attrition budget the model can spend on
|
| 100 |
+
the bait sub-force.
|
| 101 |
+
|
| 102 |
+
3. **`scout-cycle-keep-info-fresh` + `scout-track-enemy-movement`** —
|
| 103 |
+
both `capability: perception`, identical hard-tier actor list, both
|
| 104 |
+
use the `then`-chained `units_killed_gte` win predicate, both
|
| 105 |
+
probe "scout multiple times because the world changes between
|
| 106 |
+
observations." Both use the `scheduled_events:` hook (cycle =
|
| 107 |
+
reinforcement waves; track = enemy march legs). **These are
|
| 108 |
+
genuinely distinct skills** — cycle is "re-observe a stale region
|
| 109 |
+
for new arrivals", track is "follow a moving target across the
|
| 110 |
+
map." **Keep both**, but verify the briefing of each clearly
|
| 111 |
+
distinguishes the cause of staleness so the model is not asked to
|
| 112 |
+
solve cycle-by-track-strategy or vice-versa. (No action required if
|
| 113 |
+
the briefings are unambiguous, which they appear to be on
|
| 114 |
+
inspection.)
|
| 115 |
+
|
| 116 |
+
4. **`build-defensive-skirt-corners` + `build-defensive-tower-line`**
|
| 117 |
+
(strict 4-field match) **AND** the wider quartet
|
| 118 |
+
`build-defensive-tower-cluster` + `def-in-depth-vs-single`
|
| 119 |
+
(same capability + win-key set, near-identical actor list, all use
|
| 120 |
+
`rusher` bot). These four packs all probe "where do you place a
|
| 121 |
+
finite pillbox budget to survive an incoming rush?" with topology
|
| 122 |
+
variants: skirt (one in each map-relative corner of the building),
|
| 123 |
+
cluster (tight wrap), line (across the choke), depth (two thinner
|
| 124 |
+
bands). **Each topology is genuinely distinct in the optimal
|
| 125 |
+
answer**, so all four packs probe a real choice axis. **Keep all
|
| 126 |
+
four** but consider promoting them into a single named "Defense
|
| 127 |
+
Topology Suite" in the eval-cell catalog so the four cells score
|
| 128 |
+
together (one "topology-IQ" metric) rather than as four unrelated
|
| 129 |
+
reasoning packs. (No file action required; this is a catalog /
|
| 130 |
+
metric grouping recommendation.)
|
| 131 |
+
|
| 132 |
+
### 2B. Near-duplicates by win-predicate keys (informational — same
|
| 133 |
+
predicate idiom is used across distinct scenarios; verify each is
|
| 134 |
+
load-bearing)
|
| 135 |
+
|
| 136 |
+
These groups all share an identical `(capability, win_predicate_keys)`
|
| 137 |
+
fingerprint. Each group below is **not necessarily a duplicate**, but
|
| 138 |
+
flags that all members rely on the same predicate idiom and the
|
| 139 |
+
scenarios should diverge on actor composition / pressure / bot to
|
| 140 |
+
remain discriminative.
|
| 141 |
+
|
| 142 |
+
- `(reasoning, then+within_ticks)` — N=10:
|
| 143 |
+
`build-power-online-first`, `build-sequence-tech-cheapest`,
|
| 144 |
+
`build-sequence-tech-fastest`, `build-sequence-tech-most-resilient`
|
| 145 |
+
(not in cluster — was filtered earlier), `lh-econ-army-victory`,
|
| 146 |
+
`lh-opening-to-defense-to-counter`, `lh-opening-to-tech-to-army`,
|
| 147 |
+
`lh-progression-stage-locked`, `rob-objective-change-midway`,
|
| 148 |
+
`tech-balanced-econ-then-tech`,
|
| 149 |
+
`lh-build-army-coordinate-multifront-attack`. These are all
|
| 150 |
+
ordered-multi-phase scenarios. Distinct intents (build-order vs
|
| 151 |
+
long-horizon vs objective-shift); the `then` predicate is the
|
| 152 |
+
common engine machinery, not a duplication signal.
|
| 153 |
+
|
| 154 |
+
- `(reasoning, building_count_gte+building_in_region+within_ticks)` —
|
| 155 |
+
N=7: `build-sell-and-rebuild-elsewhere`, `def-in-depth`,
|
| 156 |
+
`def-tower-line-vs-cluster`, `expansion-aggro-3-base-greedy`,
|
| 157 |
+
`mcv-deploy-second-base`, `mcv-deploy-third-base`,
|
| 158 |
+
`mfb-mirror-base-east-west`. All probe "build / re-build N
|
| 159 |
+
buildings in a target region." Genuinely distinct intents
|
| 160 |
+
(expansion-greed, mirror-base symmetry, MCV-redeploy under
|
| 161 |
+
pressure); keep all.
|
| 162 |
+
|
| 163 |
+
- `(reasoning, building_count_gte+units_killed_gte+within_ticks)` —
|
| 164 |
+
N=6: `adv-rps-counter-pick`, `build-tech-skip-decision`,
|
| 165 |
+
`def-counter-battery`, `def-walls-vs-towers`, `def-while-building`,
|
| 166 |
+
`lh-tech-rush-vs-army-rush`. All "kill K enemies and have N
|
| 167 |
+
buildings standing." Reads as honest differentiated tests.
|
| 168 |
+
|
| 169 |
+
- `(action, own_units_gte+units_killed_gte+within_ticks)` — N=5:
|
| 170 |
+
`combat-flanking-attack`, `combat-harass-aggro-commit`,
|
| 171 |
+
`combat-kite-and-pull`, `combat-kite-jeep-vs-tank`,
|
| 172 |
+
`combat-tanya-vs-rush`. Five combat micro packs — kite, flank,
|
| 173 |
+
harass. Each probes a different micro idiom; keep all but verify
|
| 174 |
+
that the win bar (`units_killed_gte`) is tuned per pack so the
|
| 175 |
+
intended micro is load-bearing, not just "auto-fire wins."
|
| 176 |
+
Two are explicitly kite (`combat-kite-and-pull`,
|
| 177 |
+
`combat-kite-jeep-vs-tank`) — **possible duplicate**: kite-and-pull
|
| 178 |
+
uses generic 2tnk/3tnk vs jeep-vs-tank's unit-class asymmetry.
|
| 179 |
+
Keep both only if `combat-kite-jeep-vs-tank` actually requires the
|
| 180 |
+
jeep speed advantage that `combat-kite-and-pull` doesn't (read the
|
| 181 |
+
briefings; they look distinct).
|
| 182 |
+
|
| 183 |
+
- `(action, reach_region+units_lost_lte+within_ticks)` — N=4:
|
| 184 |
+
`proc-no-attack-passive-only`, `proc-tool-use-multi-distractor`,
|
| 185 |
+
`proc-tool-use-with-distractor`,
|
| 186 |
+
`strict-toolban-fidelity-under-pressure`. All
|
| 187 |
+
procedural-compliance packs — "reach the goal without using a
|
| 188 |
+
forbidden tool / without attacking." The `proc-tool-use-*` pair is
|
| 189 |
+
a possible duplicate: "with-distractor" (one distractor tool) vs
|
| 190 |
+
"multi-distractor" (multiple). Both are the same skill at different
|
| 191 |
+
scales — recommend collapsing into a single pack with three tiers
|
| 192 |
+
(no distractor / one / many) rather than two top-level packs.
|
| 193 |
+
|
| 194 |
+
- `(perception, buildings_discovered_gte+units_lost_lte+within_ticks)`
|
| 195 |
+
— N=4: `perception-target-vs-fog`, `scout-detect-enemy-tech`,
|
| 196 |
+
`scout-discover-hidden-base`, `scout-multiple-fog-areas`. All
|
| 197 |
+
"discover K enemy buildings under fog." Each probes a distinct
|
| 198 |
+
discrimination (target-vs-fog = ignore decoys; detect-enemy-tech =
|
| 199 |
+
read the tech-tree; hidden-base = single hidden compound;
|
| 200 |
+
multiple-fog-areas = K disjoint regions). Keep all.
|
| 201 |
+
|
| 202 |
+
### 2C. Overlapping prefixes worth a catalog review (not duplicates,
|
| 203 |
+
but the area is dense)
|
| 204 |
+
|
| 205 |
+
- `combat-*` (25 packs), `def-*` (18), `scout-*` (14), `build-*` (14),
|
| 206 |
+
`lh-*` (13), `proc-*` (10), `mfb-*` (8), `rob-*` (8), `tp-*` (7),
|
| 207 |
+
`coord-*` (7), `mcv-*` (6), `spec-*` (5), `economy-*` (5),
|
| 208 |
+
`tech-*` (4), `strategy-*` (4), `perception-*` (4), `artofwar-*` (4),
|
| 209 |
+
`tempo-*` (2), `maint-*` (2), `mid-*` (2), `expansion-*` (3),
|
| 210 |
+
`coordination-*` (2), `harass-*` (1), `risk-*` (1), `power-*` (1),
|
| 211 |
+
`navigation-*` (1), `defense-*` (1), `longhorizon-*` (1),
|
| 212 |
+
`custom-*` (1), `building-*` (1), `rush-*` (1), `reasoning-*` (2),
|
| 213 |
+
`action-*` (2), `adv-*` (2), `adversarial-*` (3), `strict-*` (3).
|
| 214 |
+
The combat / def / scout / build axes carry ~70 packs combined; a
|
| 215 |
+
follow-up audit explicitly checking pairwise overlap inside each
|
| 216 |
+
prefix (briefing-level read) would surface ~5–10 more candidate
|
| 217 |
+
collapses.
|
| 218 |
+
|
| 219 |
+
---
|
| 220 |
+
|
| 221 |
+
## Section 3 — Capability coverage matrix
|
| 222 |
+
|
| 223 |
+
Cross-referenced against the **phase × decision-type** matrix sketched
|
| 224 |
+
in `PAPER_PLAN.md §12.2` and `CLAUDE.md`. Each cell lists the packs
|
| 225 |
+
that primarily measure it (a pack may legitimately serve more than one
|
| 226 |
+
cell — only the dominant assignment is listed; cross-cutting packs are
|
| 227 |
+
flagged).
|
| 228 |
+
|
| 229 |
+
### Opening
|
| 230 |
+
|
| 231 |
+
| Decision | Packs | Density |
|
| 232 |
+
|---|---|---|
|
| 233 |
+
| MCV deploy site (where to plant) | `mcv-deploy-and-build`, `mcv-deploy-defensible-site`, `mcv-deploy-near-resource`, `mcv-deploy-relocate-under-pressure`, `mcv-deploy-second-base`, `mcv-deploy-third-base` | **6 packs** (dense; good) |
|
| 234 |
+
| Build-order commit | `build-sequence-tech-cheapest`, `build-sequence-tech-fastest`, `build-sequence-tech-most-resilient`, `build-tech-skip-decision`, `tech-balanced-econ-then-tech`, `tech-aggro-all-in`, `tech-turtle-defensive-tech`, `tech-production-planning`, `build-power-online-first`, `power-budget-online`, `building-and-planning` | **11 packs** (dense; good) |
|
| 235 |
+
| Defense-direction commit (which side to anticipate) | `def-position-expected-direction`, `def-position-revealed-direction`, `def-multi-direction`, `def-surprise-flank-react`, `def-pre-position-mobile-reserve` | **5 packs** (good) |
|
| 236 |
+
| Rush-defense | `defense-rush-survive`, `rush-hour`, `build-defensive-tower-cluster`, `build-defensive-tower-line`, `build-defensive-skirt-corners`, `def-in-depth`, `def-in-depth-vs-single`, `def-walls-vs-towers`, `def-tower-line-vs-cluster`, `def-while-building` | **10 packs** (dense) |
|
| 237 |
+
|
| 238 |
+
### Early-mid
|
| 239 |
+
|
| 240 |
+
| Decision | Packs | Density |
|
| 241 |
+
|---|---|---|
|
| 242 |
+
| Harass / harass-preserve | `harass-response-preserve`, `combat-harass-aggro-commit`, `combat-harass-balanced-hit-and-run`, `combat-skirmish-then-disengage`, `combat-bait-counter-attack`, `combat-kite-and-pull`, `combat-kite-jeep-vs-tank`, `combat-retreat-after-engagement`, `combat-suicide-charge-mission` | **9 packs** (dense) |
|
| 243 |
+
| Exact-count perception | `perception-count-the-threat`, `perception-count-the-threat-small-k`, `scout-count-defenders`, `scout-detect-incoming-army` | **4 packs** (adequate) |
|
| 244 |
+
| Scout-direction commit | `scout-detect-base-direction`, `scout-far-frontier`, `scout-frontier-reading` (=`perception-frontier-reading`), `scout-multiple-fog-areas`, `scout-and-report`, `scout-and-survive`, `scout-discover-hidden-base`, `scout-detect-enemy-tech`, `scout-map-reveal-percent-target`, `reasoning-frontier-commit` | **10 packs** (dense; possible over-coverage) |
|
| 245 |
+
|
| 246 |
+
### Mid
|
| 247 |
+
|
| 248 |
+
| Decision | Packs | Density |
|
| 249 |
+
|---|---|---|
|
| 250 |
+
| Live-economy defense | `mid-economy-under-fire` (**DEFECT — stall wins**), `econ-harvester-defense-raid` [skipped — econ-*], `econ-protect-harvester-route` [skipped] | **~3 packs, 1 defective** — the only non-econ exemplar is broken. **Gap when the in-flight econ-* land — verify they cover.** |
|
| 251 |
+
| Tech-switch on scout | `mid-tech-switch-on-scout`, `lh-scout-react-counter`, `adv-rps-counter-pick` | **3 packs** (adequate) |
|
| 252 |
+
| Second front | `mfb-base-1-defend-base-2-build`, `mfb-supply-line-link-between-bases`, `mfb-mirror-base-east-west`, `mfb-two-base-simultaneous`, `mfb-third-base-against-clock`, `expansion-balanced-2-base-defended`, `expansion-aggro-3-base-greedy`, `coord-diversionary-attack` | **8 packs** (dense) |
|
| 253 |
+
| Replan after loss | `rob-unit-loss-recovery`, `rob-partial-base-loss-continue`, `lh-recovery-after-mid-game-loss`, `build-engineer-rebuild-after-loss`, `def-retreat-and-rebuild`, `build-sell-and-rebuild-elsewhere` | **6 packs** (good) |
|
| 254 |
+
|
| 255 |
+
### Mid-late
|
| 256 |
+
|
| 257 |
+
| Decision | Packs | Density |
|
| 258 |
+
|---|---|---|
|
| 259 |
+
| Concede vs hold | `mid-concede-vs-hold` | **1 pack** (THIN — single exemplar) |
|
| 260 |
+
| Isolate vs split | `combat-divide-and-conquer`, `combat-pincer-coordination`, `combat-prevent-retreat`, `combat-formation-tank-wedge` | **4 packs** (adequate) |
|
| 261 |
+
| Tempo double-window | `tempo-double-window`, `tempo-strike-window`, `coordination-staggered-window`, `tp-survive-and-strike-at-window` | **4 packs** (adequate) |
|
| 262 |
+
| Decoy / lure / feint | `artofwar-decoy-sacrifice`, `artofwar-lure-the-tiger`, `artofwar-indirect-approach`, `artofwar-sequenced-citadel`, `combat-bait-counter-attack`, `coord-diversionary-attack`, `def-with-ambush` | **7 packs** (good) |
|
| 263 |
+
| Multi-front | `mfb-rotating-production-pressure`, `mfb-redundant-tech-buildings`, `mfb-tech-base-vs-economy-base`, `rob-multiple-simultaneous-pressures` | **4 packs** (adequate) |
|
| 264 |
+
|
| 265 |
+
### Late
|
| 266 |
+
|
| 267 |
+
| Decision | Packs | Density |
|
| 268 |
+
|---|---|---|
|
| 269 |
+
| Sustained multi-front | `lh-build-army-coordinate-multifront-attack`, `mfb-rotating-production-pressure` | **2 packs** (thin) |
|
| 270 |
+
| Base-trade race | None directly | **0 packs (GAP)** |
|
| 271 |
+
| Counter-strategy read | `adv-rps-counter-pick`, `combat-attack-from-behind-fog`, `lh-tech-rush-vs-army-rush` | **3 packs** (adequate) |
|
| 272 |
+
| Superweapon timing | `spec-nuke-strike`, `spec-tanya-c4-strike`, `spec-engineer-capture`, `spec-spy-infiltrate` (**DEFECT — stall draws**), `spec-thief-steal-cash` | **5 packs, 1 defective** (good once spec-spy is fixed) |
|
| 273 |
+
| Credit-only final phase | `lh-credit-only-final-phase` | **1 pack** (thin) |
|
| 274 |
+
|
| 275 |
+
### Cross-cutting
|
| 276 |
+
|
| 277 |
+
| Capability | Packs | Density |
|
| 278 |
+
|---|---|---|
|
| 279 |
+
| Procedural compliance under pressure | `proc-checklist-no-deviation`, `proc-conditional-branch-action`, `proc-instruction-following-edge-case`, `proc-no-attack-passive-only`, `proc-only-build-no-combat`, `proc-only-defend-no-attack`, `proc-ordered-action-strict`, `proc-strict-toolban-fidelity`, `proc-tool-use-multi-distractor`, `proc-tool-use-with-distractor`, `strict-production-bom`, `strict-sequence`, `strict-toolban-fidelity-under-pressure`, `tp-pressure-procedural` | **14 packs** (very dense) |
|
| 280 |
+
| Long-horizon multi-phase | `lh-*` (13 packs), `longhorizon-opening-to-assault`, `lh-100-turn-marathon-survival` | **14 packs** (dense) |
|
| 281 |
+
| Coordination across squads | `coord-converge-on-target`, `coord-cover-and-move`, `coord-diversionary-attack`, `coord-mutual-support`, `coord-relay-attack`, `coord-relay-vision-chain`, `coord-squad-handoff`, `coordination-ordered-rendezvous`, `coordination-staggered-window`, `action-multiunit-coordination`, `action-sequenced-execution`, `combat-pincer-coordination`, `combat-heli-flank` | **13 packs** (dense) |
|
| 282 |
+
| Adversarial 1v1 (full macro) | `adversarial-duel`. The full 1v1 battleground lives in `one_v_one.py` (`openra_bench/`), not as a `meta.capability: adversarial` pack. | **1 pack** (the catalog says this is by design — full macro is the live ladder) |
|
| 283 |
+
|
| 284 |
+
---
|
| 285 |
+
|
| 286 |
+
## Section 4 — Capability gaps (uncovered or thin cells)
|
| 287 |
+
|
| 288 |
+
Cells worth new packs, in priority order:
|
| 289 |
+
|
| 290 |
+
1. **Base-trade race (mid-late / late)** — *no* current pack tests
|
| 291 |
+
"your base falls while you race the enemy's; whoever finishes first
|
| 292 |
+
wins." Sketch: hard tier places both players' bases halfway to
|
| 293 |
+
killable, no defenders left; the agent has one army worth attacking
|
| 294 |
+
with, the enemy is doing the same to the agent's base; win by
|
| 295 |
+
destroying the enemy's `fact` before they destroy yours. Win
|
| 296 |
+
`building_count_gte:{type:fact,n:0,owner:enemy}` paired with
|
| 297 |
+
`has_building:fact` (own) and an aggressive `within_ticks`. Pack id:
|
| 298 |
+
`combat-base-trade-race`.
|
| 299 |
+
|
| 300 |
+
2. **Concede-vs-hold (mid-late)** — only `mid-concede-vs-hold`
|
| 301 |
+
currently. Sketch a second pack: `mid-concede-vs-rebuild` where a
|
| 302 |
+
forward outpost is lost-cost (committing reinforcements throws
|
| 303 |
+
good money after bad), and the right call is to abandon it and
|
| 304 |
+
rebuild on a held line. Win condition: keep the rear-line `fact`
|
| 305 |
+
alive AND have ≥4 `tent`/`weap` on the rear line at deadline;
|
| 306 |
+
throwing reinforcements at the forward outpost fails the resource
|
| 307 |
+
budget. Pack id: `mid-concede-forward-rebuild-rear`.
|
| 308 |
+
|
| 309 |
+
3. **Live economy defense (mid)** — the only non-econ pack
|
| 310 |
+
(`mid-economy-under-fire`) is currently a stall-WIN defect. After
|
| 311 |
+
fixing it, add a sibling pack `mid-economy-rebuild-harvester-line`
|
| 312 |
+
where the agent must re-issue `harvest` commands to a freshly
|
| 313 |
+
produced harvester after a raider kills the starter ones (puts
|
| 314 |
+
the load-bearing capability on the `harvest` order, not on the
|
| 315 |
+
passive auto-harvest).
|
| 316 |
+
|
| 317 |
+
4. **Long-horizon credit-only final phase** — `lh-credit-only-final-phase`
|
| 318 |
+
is the only exemplar. Sketch sibling: `lh-credit-only-bait-window` —
|
| 319 |
+
the agent must spend the last credits on a single decisive strike
|
| 320 |
+
window rather than on attrition. Different decision (one shot vs
|
| 321 |
+
accumulation).
|
| 322 |
+
|
| 323 |
+
5. **Sustained multi-front (late)** — thin (2 packs). Sketch:
|
| 324 |
+
`mfb-three-front-rotation` — three simultaneously-attacked bases
|
| 325 |
+
with the agent's army too small to defend all three at once; the
|
| 326 |
+
decision is which two to hold and which one to let fall while the
|
| 327 |
+
army cycles. Cross-pack with `coord-relay-attack`.
|
| 328 |
+
|
| 329 |
+
6. **MCV deploy under timer + crossfire** — current MCV packs cover
|
| 330 |
+
site selection but not "deploy NOW or the MCV is destroyed by an
|
| 331 |
+
incoming wave that hits in 4 turns." Sketch:
|
| 332 |
+
`mcv-deploy-emergency-relocation` — the starting MCV stands in the
|
| 333 |
+
path of an incoming squad; the agent must deploy + re-build OR
|
| 334 |
+
move + re-deploy further west before the squad arrives.
|
| 335 |
+
|
| 336 |
+
7. **Information freshness across modalities** — `scout-cycle-keep-info-fresh`
|
| 337 |
+
and `scout-track-enemy-movement` cover this for the structured
|
| 338 |
+
channel, but the perception ablation grid (channel × fog) doesn't
|
| 339 |
+
currently have an information-freshness pack that is explicitly
|
| 340 |
+
easier to solve with the labelled image (the `image` channel is
|
| 341 |
+
advantaged when the model can spot newly-spawned units
|
| 342 |
+
inter-tick). Sketch: `perception-freshness-image-advantage`.
|
| 343 |
+
|
| 344 |
+
8. **Single-pack `meta.capability: adversarial`** — only
|
| 345 |
+
`adversarial-duel` carries this tag. PAPER_PLAN.md §12.2 notes the
|
| 346 |
+
imbalance. The full 1v1 lives in `one_v_one.py` (correct), but a
|
| 347 |
+
second adversarial-tagged pack that tests "reactive opponent
|
| 348 |
+
selects a counter from a small menu mid-game" (different from RPS
|
| 349 |
+
pre-game commit) would put real teeth on the tag.
|
| 350 |
+
|
| 351 |
+
9. **Engineer / Tanya / spy under fire** (specialist packs) — only one
|
| 352 |
+
pack each (`spec-engineer-capture`, `spec-tanya-c4-strike`,
|
| 353 |
+
`spec-spy-infiltrate`, `spec-thief-steal-cash`, `combat-tanya-vs-rush`).
|
| 354 |
+
Each specialist has one happy-path scenario. Sketch a "stealth +
|
| 355 |
+
target priority" pack per specialist that requires the model to
|
| 356 |
+
pick *which* of N enemy assets to hit with the one-shot specialist.
|
| 357 |
+
|
| 358 |
+
10. **Naval / amphibious** — `combat-naval-shore-strike` is the only
|
| 359 |
+
naval pack (and it's currently a stall-WIN defect). Once fixed,
|
| 360 |
+
add `combat-naval-amphibious-landing` (a transport ship lands
|
| 361 |
+
infantry on a contested shore) and `combat-naval-anti-air-vs-bomber`
|
| 362 |
+
pending the air-unit engine work. These are documented as
|
| 363 |
+
out-of-scope in `PAPER_PLAN.md §11.1` for the air variant but the
|
| 364 |
+
naval ones are now feasible thanks to `water_rect:`.
|
| 365 |
+
|
| 366 |
+
---
|
| 367 |
+
|
| 368 |
+
## Section 5 — Map mis-bindings (rush-hour-arena used where intent
|
| 369 |
+
calls for a custom map)
|
| 370 |
+
|
| 371 |
+
Of 189 probed packs, **183** use `rush-hour-arena`; **3** use a custom
|
| 372 |
+
map (`navigation-confined-hard-only`, `custom-map-no-enemy`,
|
| 373 |
+
`strategy-dilemma`/`-gauntlet`/`-twobody`); **1** uses a generator
|
| 374 |
+
(`combat-naval-shore-strike`); **2** are quarantined-and-crashing.
|
| 375 |
+
|
| 376 |
+
Packs whose stated intent calls for a non-rush-hour geometry:
|
| 377 |
+
|
| 378 |
+
| Pack | Stated intent | Current map | Recommendation |
|
| 379 |
+
|---|---|---|---|
|
| 380 |
+
| `combat-heli-flank` | Helicopter assault from a flank; the brief explicitly references aircraft flight over terrain. | rush-hour-arena (no terrain features to flank around) | Author / use a custom map with a forested ridge that channels ground units one way and aircraft another. (Engine air-unit support is out-of-scope per PAPER_PLAN §11.1 — pack is currently a ground-only proxy.) |
|
| 381 |
+
| `def-bridge-chokepoint` | "A water band cuts the map east-to-west with bridges." | rush-hour-arena + `water_rect` overlay | The `water_rect` overlay correctly synthesizes the bridge geometry on top of rush-hour, but the chokepoint-narrowing aspect ("attackers must pass through 3 narrow openings") works against an open-arena map. Consider a custom `bridges-arena` map authored once — the visual / minimap reading test is more honest when the bridges are real terrain rather than a YAML overlay on an unrelated map. |
|
| 382 |
+
| `combat-naval-shore-strike` | Naval ship in a water channel. | uses `naval-arena` generator (correct) — but the generator spec lives in the pack file rather than a named `.oramap`. | When a second naval pack is authored (per gap #10), promote `naval-arena` to a real `data/maps/naval-arena.oramap` so the bench has a canonical naval geometry. |
|
| 383 |
+
| `def-with-ambush` | "Concealed flanking defenders catch the band in an L-ambush down a lane toward the construction yard." Doctrinal answer requires real linear terrain. | rush-hour-arena (open) | The pack synthesizes the lane purely with actor placement (a single `e1` fixing defender at x=15, flankers at x=40). Visually the geometry is invisible on the minimap — a custom `corridor-arena` map with a real lane would make the spatial decision legible from the image. (Capability is sound; this is a perception-channel polish issue.) |
|
| 384 |
+
| `mfb-supply-line-link-between-bases` | "Supply line corridor between two bases." | rush-hour-arena | Similar polish issue — a custom multi-base map with two separated valleys would make the supply-line decision visible on the minimap rather than implicit in the actor coordinates. |
|
| 385 |
+
| `combat-hold-chokepoint` | "Defend a narrow chokepoint corridor." | rush-hour-arena (no narrow corridor) | Same; either author a `chokepoint-arena` map or accept that the chokepoint is implied by enemy spawn geometry alone. |
|
| 386 |
+
| `mcv-deploy-second-base`, `mcv-deploy-third-base` | "Plant a second / third base at a defensible site." | rush-hour-arena (uniform; no defensible sites) | The map is symmetric and uniform — every cell is roughly as defensible as every other. The capability becomes "pick a cell that satisfies the `building_in_region` predicate," not "pick a *defensible* cell." Add a custom map with terrain features (cliff edges, narrow passes) so the defensibility geometry is real. |
|
| 387 |
+
| `expansion-aggro-3-base-greedy`, `expansion-balanced-2-base-defended`, `expansion-turtle-1-base-fortified` | Expansion decisions over distinct base sites. | rush-hour-arena (only ~3 sensible base sites given map size) | Authoring a wider arena with 5+ distinguishable expansion sites would put real teeth on the trilemma. |
|
| 388 |
+
|
| 389 |
+
**Summary**: roughly 8–10 packs would benefit from a custom map, but
|
| 390 |
+
all are currently *functional* (the no-cheat bar holds). The map
|
| 391 |
+
mis-binding is a perception-channel polish issue, not a correctness
|
| 392 |
+
issue. **Priority**: author 2 custom maps that unlock several packs
|
| 393 |
+
each:
|
| 394 |
+
1. `bridges-arena` — would replace `water_rect` overlay on
|
| 395 |
+
`def-bridge-chokepoint` and could host `combat-naval-amphibious-landing`.
|
| 396 |
+
2. `chokepoint-arena` — narrow corridor for `combat-hold-chokepoint`,
|
| 397 |
+
`def-with-ambush`, `mfb-supply-line-link-between-bases`.
|
| 398 |
+
|
| 399 |
+
---
|
| 400 |
+
|
| 401 |
+
## Section 6 — Recommended actions (prioritized)
|
| 402 |
+
|
| 403 |
+
### P0 — Hard defects (gates the no-cheat headline number)
|
| 404 |
+
|
| 405 |
+
1. **Fix `mid-economy-under-fire`** — currently the only stall-WIN
|
| 406 |
+
defect among non-exempt packs. Either:
|
| 407 |
+
- (a) Remove the 3 starter harvesters; require the model to issue
|
| 408 |
+
`Command.harvest(...)` on a fresh harvester (the load-bearing
|
| 409 |
+
capability), OR
|
| 410 |
+
- (b) Upgrade the raider to a force that out-attritions an idle
|
| 411 |
+
defense ring (e.g. 3× `1tnk` + 2× `e3` over 60 turns), so a
|
| 412 |
+
stall play loses harvesters and the `harv,2` clause fails.
|
| 413 |
+
|
| 414 |
+
2. **Fix `combat-naval-shore-strike`** — set the destroyer `stance` to
|
| 415 |
+
`0` (HoldFire) so the agent must issue an explicit `attack_unit`
|
| 416 |
+
order. Verify the intended capability (manual cross-shore attack)
|
| 417 |
+
still wins; stall now loses by deadline.
|
| 418 |
+
|
| 419 |
+
3. **Fix `spec-spy-infiltrate`** — add `{not: own_units_gte: 1}` (or
|
| 420 |
+
`{not: unit_type_count_gte: {type: spy, n: 1}}`) to the
|
| 421 |
+
`fail_condition.any_of` so a spy-wipe is a real LOSS, not a
|
| 422 |
+
DRAW. Audit the easy / medium tiers for the same defect.
|
| 423 |
+
|
| 424 |
+
4. **Delete or `_archive/` `adversarial-siege` and `adversarial-skirmish`** —
|
| 425 |
+
both already quarantined; deletion removes the only two
|
| 426 |
+
load-time-crashing packs.
|
| 427 |
+
|
| 428 |
+
5. **Re-probe `def-bridge-chokepoint` over seeds 1–4 in clean processes**
|
| 429 |
+
— confirm the one-off DRAW observation was a transient (subsequent
|
| 430 |
+
re-runs gave LOSS consistently); if the DRAW recurs, add
|
| 431 |
+
`{not: own_units_gte: 1}` to its `fail_condition.any_of`.
|
| 432 |
+
|
| 433 |
+
### P1 — Coverage gaps (new packs to author)
|
| 434 |
+
|
| 435 |
+
In priority order from §4: `combat-base-trade-race`,
|
| 436 |
+
`mid-concede-forward-rebuild-rear`, `mid-economy-rebuild-harvester-line`,
|
| 437 |
+
`mfb-three-front-rotation`, `mcv-deploy-emergency-relocation`,
|
| 438 |
+
`lh-credit-only-bait-window`, `perception-freshness-image-advantage`,
|
| 439 |
+
`combat-naval-amphibious-landing`, and per-specialist target-priority
|
| 440 |
+
packs (`spec-engineer-priority-targets`, `spec-tanya-priority-targets`).
|
| 441 |
+
|
| 442 |
+
### P2 — Duplicate consolidation
|
| 443 |
+
|
| 444 |
+
1. Merge / delete `artofwar-decoy-sacrifice` into
|
| 445 |
+
`artofwar-lure-the-tiger`.
|
| 446 |
+
2. Merge `proc-tool-use-with-distractor` + `proc-tool-use-multi-distractor`
|
| 447 |
+
into a single pack with two tiers.
|
| 448 |
+
3. Re-read `combat-kite-and-pull` vs `combat-kite-jeep-vs-tank` and
|
| 449 |
+
either merge or sharpen the asymmetry-of-units distinction in the
|
| 450 |
+
second pack's briefing.
|
| 451 |
+
|
| 452 |
+
### P3 — Map / catalog polish
|
| 453 |
+
|
| 454 |
+
1. Author `data/maps/bridges-arena.oramap` and re-bind
|
| 455 |
+
`def-bridge-chokepoint` + (future) `combat-naval-amphibious-landing`.
|
| 456 |
+
2. Author `data/maps/chokepoint-arena.oramap` and re-bind
|
| 457 |
+
`def-with-ambush`, `combat-hold-chokepoint`,
|
| 458 |
+
`mfb-supply-line-link-between-bases`.
|
| 459 |
+
3. Promote the four "defensive topology" packs
|
| 460 |
+
(`build-defensive-tower-cluster`, `build-defensive-tower-line`,
|
| 461 |
+
`build-defensive-skirt-corners`, `def-in-depth-vs-single`) into a
|
| 462 |
+
single grouped eval-cell suite so they score one "topology-IQ"
|
| 463 |
+
metric.
|
| 464 |
+
|
| 465 |
+
---
|
| 466 |
+
|
| 467 |
+
## Appendix — Probe methodology
|
| 468 |
+
|
| 469 |
+
Each pack was probed by:
|
| 470 |
+
|
| 471 |
+
```python
|
| 472 |
+
import openra_train # builds the engine; required for env.reset
|
| 473 |
+
from openra_bench.scenarios.loader import compile_level, load_pack
|
| 474 |
+
from openra_bench.eval_core import run_level
|
| 475 |
+
|
| 476 |
+
pack = load_pack(pack_yaml_path)
|
| 477 |
+
c = compile_level(pack, "hard")
|
| 478 |
+
ep = run_level(c, lambda rs, Command: [Command.observe()], seed=1)
|
| 479 |
+
# ep.outcome ∈ {"win", "loss", "draw"}; ep.signals.game_tick = final tick.
|
| 480 |
+
```
|
| 481 |
+
|
| 482 |
+
The driver (`/tmp/stall_probe_driver.py`) invoked one subprocess per
|
| 483 |
+
pack so a Rust engine panic in any one pack did not abort the run.
|
| 484 |
+
189 packs probed in 48 seconds wall-time (Apple M-series).
|
| 485 |
+
|
| 486 |
+
Hard tier seed=1 only. A full audit would extend to seeds 1–4 (the
|
| 487 |
+
documented "hard seed" range in CLAUDE.md) and to easy/medium tiers,
|
| 488 |
+
but seed-1 hard is the highest-pressure cell per pack — defects
|
| 489 |
+
visible on any tier are visible here.
|
| 490 |
+
|
| 491 |
+
Static profile was extracted from the compiled `CompiledLevel`
|
| 492 |
+
(authoritative — the engine sees the merged scenario, not the raw
|
| 493 |
+
YAML).
|
| 494 |
+
|
| 495 |
+
Raw probe results JSON: `/tmp/stall_probe_results.json` (regeneratable
|
| 496 |
+
by re-running `/tmp/stall_probe_driver.py`).
|
|
Binary files a/data/maps/confined-aisle-64x40.oramap and b/data/maps/confined-aisle-64x40.oramap differ
|
|
|
|
Binary files a/data/maps/expansion-aggro-3-base-greedy-arena.oramap and b/data/maps/expansion-aggro-3-base-greedy-arena.oramap differ
|
|
|
|
Binary files a/data/maps/gen-arena-31f6567b.oramap and b/data/maps/gen-arena-31f6567b.oramap differ
|
|
|
|
Binary files a/data/maps/gen-arena-498d46e9.oramap and b/data/maps/gen-arena-498d46e9.oramap differ
|
|
|
|
Binary files a/data/maps/lh-defense-tech-second-base-arena.oramap and b/data/maps/lh-defense-tech-second-base-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mcv-deploy-third-base-arena.oramap and b/data/maps/mcv-deploy-third-base-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mfb-base-1-defend-base-2-build-arena.oramap and b/data/maps/mfb-base-1-defend-base-2-build-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mfb-mirror-base-east-west-arena.oramap and b/data/maps/mfb-mirror-base-east-west-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mfb-supply-line-corridor-arena.oramap and b/data/maps/mfb-supply-line-corridor-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mfb-third-base-against-clock-arena.oramap and b/data/maps/mfb-third-base-against-clock-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mfb-two-base-simultaneous-arena.oramap and b/data/maps/mfb-two-base-simultaneous-arena.oramap differ
|
|
|
|
Binary files a/data/maps/mid-concede-arena.oramap and b/data/maps/mid-concede-arena.oramap differ
|
|
|
|
Binary files a/data/maps/naval-arena-64x40.oramap and b/data/maps/naval-arena-64x40.oramap differ
|
|
|
|
Binary files a/data/maps/scout-arena.oramap and b/data/maps/scout-arena.oramap differ
|
|
|
|
@@ -616,6 +616,16 @@ class ModelAgent:
|
|
| 616 |
)
|
| 617 |
self.history: list[dict] = [{"role": "system", "content": sys_content}]
|
| 618 |
self.stats = {"turns": 0, "tool_calls": 0, "empty_replies": 0}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
# Controller contract (openra_bench/controller.py): a ModelAgent
|
| 620 |
# IS a Controller — it exposes `name`, `reset`, `act` so the
|
| 621 |
# eval loop, the 1v1 harness, and the human-labeling harness can
|
|
@@ -768,12 +778,44 @@ class ModelAgent:
|
|
| 768 |
|
| 769 |
def agent_fn(self, render_state: dict, Command: Any) -> list:
|
| 770 |
self.stats["turns"] += 1
|
| 771 |
-
self.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 772 |
self._strip_old_images(self.history)
|
| 773 |
wire = self._window(
|
| 774 |
self.history, getattr(self.cfg, "max_history_turns", 16)
|
| 775 |
)
|
| 776 |
reply = self.provider.complete(wire, self.tools)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 777 |
self.history.append(
|
| 778 |
{
|
| 779 |
"role": "assistant",
|
|
|
|
| 616 |
)
|
| 617 |
self.history: list[dict] = [{"role": "system", "content": sys_content}]
|
| 618 |
self.stats = {"turns": 0, "tool_calls": 0, "empty_replies": 0}
|
| 619 |
+
# Audit-format capture (FullPlayback). When `audit_capture` is
|
| 620 |
+
# True the agent stores the per-turn briefing, the provider's
|
| 621 |
+
# literal request/response, and exposes the system prompt so
|
| 622 |
+
# the audit JSONL line for the turn carries everything.
|
| 623 |
+
# Default off — zero overhead for normal runs.
|
| 624 |
+
self.audit_capture: bool = False
|
| 625 |
+
self.last_briefing: str = ""
|
| 626 |
+
self.last_request: dict | None = None
|
| 627 |
+
self.last_response: dict | None = None
|
| 628 |
+
self.system_prompt: str = sys_content
|
| 629 |
# Controller contract (openra_bench/controller.py): a ModelAgent
|
| 630 |
# IS a Controller — it exposes `name`, `reset`, `act` so the
|
| 631 |
# eval loop, the 1v1 harness, and the human-labeling harness can
|
|
|
|
| 778 |
|
| 779 |
def agent_fn(self, render_state: dict, Command: Any) -> list:
|
| 780 |
self.stats["turns"] += 1
|
| 781 |
+
user_msg = self._user_message(render_state)
|
| 782 |
+
if self.audit_capture:
|
| 783 |
+
# Plain-text briefing capture (image-primary turns carry a
|
| 784 |
+
# list `content`; the text part is the briefing). FullPlayback
|
| 785 |
+
# writes this as the human-readable `briefing` field so the
|
| 786 |
+
# audit JSONL records exactly what the model read.
|
| 787 |
+
c = user_msg.get("content")
|
| 788 |
+
if isinstance(c, str):
|
| 789 |
+
self.last_briefing = c
|
| 790 |
+
elif isinstance(c, list):
|
| 791 |
+
self.last_briefing = "\n".join(
|
| 792 |
+
p.get("text", "") for p in c
|
| 793 |
+
if isinstance(p, dict) and p.get("type") == "text"
|
| 794 |
+
)
|
| 795 |
+
# Enable provider-side audit hook for this turn (drain on
|
| 796 |
+
# return). Lazily install the list — providers without the
|
| 797 |
+
# `request_log` attr (e.g. Bedrock stub) silently skip.
|
| 798 |
+
if hasattr(self.provider, "request_log"):
|
| 799 |
+
self.provider.request_log = []
|
| 800 |
+
self.history.append(user_msg)
|
| 801 |
self._strip_old_images(self.history)
|
| 802 |
wire = self._window(
|
| 803 |
self.history, getattr(self.cfg, "max_history_turns", 16)
|
| 804 |
)
|
| 805 |
reply = self.provider.complete(wire, self.tools)
|
| 806 |
+
if self.audit_capture and hasattr(self.provider, "request_log"):
|
| 807 |
+
log = self.provider.request_log or []
|
| 808 |
+
# One model call per turn (no internal retries here — those
|
| 809 |
+
# are surfaced as a single call with the eventual response);
|
| 810 |
+
# take the LAST entry to be safe.
|
| 811 |
+
if log:
|
| 812 |
+
self.last_request = log[-1].get("request")
|
| 813 |
+
self.last_response = log[-1].get("response")
|
| 814 |
+
else:
|
| 815 |
+
self.last_request = None
|
| 816 |
+
self.last_response = None
|
| 817 |
+
# Drain so the next turn starts clean.
|
| 818 |
+
self.provider.request_log = []
|
| 819 |
self.history.append(
|
| 820 |
{
|
| 821 |
"role": "assistant",
|
|
@@ -230,6 +230,7 @@ def run_level(
|
|
| 230 |
agent_fn: "AgentFn | Controller" = scripted_explore_agent,
|
| 231 |
seed: int = 0,
|
| 232 |
playback=None,
|
|
|
|
| 233 |
) -> EpisodeResult:
|
| 234 |
"""Run one scenario-pack level, scoring against its declarative
|
| 235 |
win/fail conditions (checked every turn). Outcome maps to the
|
|
@@ -272,6 +273,15 @@ def run_level(
|
|
| 272 |
# model actually saw (same vendored _minimap_v2, accumulating).
|
| 273 |
_pb_explored: set = set()
|
| 274 |
_pb_terrain = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
# Interrupt-driven mode (step 4): if the scenario enabled any
|
| 276 |
# interrupt signals, advance with step_until_event so the agent
|
| 277 |
# is re-prompted (debriefed) the moment an event fires
|
|
@@ -356,6 +366,57 @@ def run_level(
|
|
| 356 |
interrupt=interrupt,
|
| 357 |
goal=turn_goal(compiled.win_condition, ctx),
|
| 358 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
trace.append(
|
| 360 |
{
|
| 361 |
"turn": turns,
|
|
@@ -454,8 +515,43 @@ def run_level(
|
|
| 454 |
},
|
| 455 |
}
|
| 456 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 457 |
return result
|
| 458 |
finally:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
pool.release(env)
|
| 460 |
pool.shutdown()
|
| 461 |
Path(tmp_path).unlink(missing_ok=True)
|
|
|
|
| 230 |
agent_fn: "AgentFn | Controller" = scripted_explore_agent,
|
| 231 |
seed: int = 0,
|
| 232 |
playback=None,
|
| 233 |
+
full_playback=None,
|
| 234 |
) -> EpisodeResult:
|
| 235 |
"""Run one scenario-pack level, scoring against its declarative
|
| 236 |
win/fail conditions (checked every turn). Outcome maps to the
|
|
|
|
| 273 |
# model actually saw (same vendored _minimap_v2, accumulating).
|
| 274 |
_pb_explored: set = set()
|
| 275 |
_pb_terrain = None
|
| 276 |
+
# Audit-capture wiring: when a FullPlayback is attached, surface
|
| 277 |
+
# the underlying ModelAgent (if any) and flip on `audit_capture`
|
| 278 |
+
# so per-turn briefing / wire request+response are stashed for
|
| 279 |
+
# the audit JSONL.
|
| 280 |
+
_audit_agent = (
|
| 281 |
+
introspection_source(controller) if full_playback is not None else None
|
| 282 |
+
)
|
| 283 |
+
if _audit_agent is not None and hasattr(_audit_agent, "audit_capture"):
|
| 284 |
+
_audit_agent.audit_capture = True
|
| 285 |
# Interrupt-driven mode (step 4): if the scenario enabled any
|
| 286 |
# interrupt signals, advance with step_until_event so the agent
|
| 287 |
# is re-prompted (debriefed) the moment an event fires
|
|
|
|
| 366 |
interrupt=interrupt,
|
| 367 |
goal=turn_goal(compiled.win_condition, ctx),
|
| 368 |
)
|
| 369 |
+
if full_playback is not None:
|
| 370 |
+
# Mirror the same PNG (when the legacy playback rendered
|
| 371 |
+
# one). Otherwise render on-demand for the audit format.
|
| 372 |
+
_fp_png = locals().get("_png") if playback is not None else None
|
| 373 |
+
if _fp_png is None:
|
| 374 |
+
try:
|
| 375 |
+
from .minimap import terrain_png_for
|
| 376 |
+
if _pb_terrain is None:
|
| 377 |
+
_pb_terrain = terrain_png_for(
|
| 378 |
+
compiled.scenario.base_map
|
| 379 |
+
)
|
| 380 |
+
from .prompt_v2 import minimap_b64 as _v2_mm
|
| 381 |
+
_fp_png = _v2_mm(
|
| 382 |
+
rs, _pb_terrain, _pb_explored,
|
| 383 |
+
constant_colors=compiled.level in ("easy", "medium"),
|
| 384 |
+
)
|
| 385 |
+
if _fp_png is None:
|
| 386 |
+
from .agent import _render_minimap_b64
|
| 387 |
+
_fp_png = _render_minimap_b64(rs, _pb_terrain)
|
| 388 |
+
except Exception: # noqa: BLE001 — audit never breaks a run
|
| 389 |
+
_fp_png = None
|
| 390 |
+
try:
|
| 391 |
+
full_playback.record_turn(
|
| 392 |
+
turn=turns,
|
| 393 |
+
tick=adapter.signals.game_tick,
|
| 394 |
+
obs=rs,
|
| 395 |
+
briefing=getattr(_audit_agent, "last_briefing", "")
|
| 396 |
+
if _audit_agent is not None
|
| 397 |
+
else "",
|
| 398 |
+
system_prompt=getattr(_audit_agent, "system_prompt", "")
|
| 399 |
+
if _audit_agent is not None
|
| 400 |
+
else "",
|
| 401 |
+
model_request=getattr(_audit_agent, "last_request", None)
|
| 402 |
+
if _audit_agent is not None
|
| 403 |
+
else None,
|
| 404 |
+
model_response=getattr(_audit_agent, "last_response", None)
|
| 405 |
+
if _audit_agent is not None
|
| 406 |
+
else None,
|
| 407 |
+
commands_issued=cmds,
|
| 408 |
+
engine_warnings=(
|
| 409 |
+
info.get("warnings", [])
|
| 410 |
+
if isinstance(info, dict)
|
| 411 |
+
else []
|
| 412 |
+
),
|
| 413 |
+
signals=adapter.signals,
|
| 414 |
+
minimap_png_b64=_fp_png,
|
| 415 |
+
done=bool(done),
|
| 416 |
+
interrupt=interrupt,
|
| 417 |
+
)
|
| 418 |
+
except Exception: # noqa: BLE001
|
| 419 |
+
pass
|
| 420 |
trace.append(
|
| 421 |
{
|
| 422 |
"turn": turns,
|
|
|
|
| 515 |
},
|
| 516 |
}
|
| 517 |
)
|
| 518 |
+
if full_playback is not None:
|
| 519 |
+
try:
|
| 520 |
+
full_playback.finalize(
|
| 521 |
+
outcome=outcome,
|
| 522 |
+
final_obs=final_rs,
|
| 523 |
+
manifest_extra={
|
| 524 |
+
"scenario": result.scenario,
|
| 525 |
+
"pack_id": compiled.pack_id,
|
| 526 |
+
"level": compiled.level,
|
| 527 |
+
"capability": compiled.meta.capability,
|
| 528 |
+
"seed": seed,
|
| 529 |
+
"outcome": outcome,
|
| 530 |
+
"turns": turns,
|
| 531 |
+
"max_turns": compiled.max_turns,
|
| 532 |
+
"actions_issued": issued,
|
| 533 |
+
"actions_warned": warned,
|
| 534 |
+
"agent_stats": getattr(
|
| 535 |
+
introspection_source(controller), "stats", None
|
| 536 |
+
),
|
| 537 |
+
"objective_progress": result.objective_progress,
|
| 538 |
+
"reward_vector": result.reward_vector,
|
| 539 |
+
},
|
| 540 |
+
)
|
| 541 |
+
except Exception: # noqa: BLE001 — never break a run on I/O
|
| 542 |
+
pass
|
| 543 |
return result
|
| 544 |
finally:
|
| 545 |
+
# Abort the audit recorder if the loop crashed before finalize —
|
| 546 |
+
# leaves a `.partial` on disk for forensics; the resume scanner
|
| 547 |
+
# correctly sees no `.jsonl` and retries the cell.
|
| 548 |
+
try:
|
| 549 |
+
if full_playback is not None and Path(
|
| 550 |
+
full_playback.jsonl_path
|
| 551 |
+
).exists() is False:
|
| 552 |
+
full_playback.abort()
|
| 553 |
+
except Exception: # noqa: BLE001
|
| 554 |
+
pass
|
| 555 |
pool.release(env)
|
| 556 |
pool.shutdown()
|
| 557 |
Path(tmp_path).unlink(missing_ok=True)
|
|
@@ -0,0 +1,334 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Audit-ready per-cell data capture (Phase 4 paper-collection format).
|
| 2 |
+
|
| 3 |
+
This is the **audit format** used by `scripts/collect_eval_data.py`. It
|
| 4 |
+
is additive over `openra_bench.playback.Playback`: that one stays the
|
| 5 |
+
inspect-by-human format (legible per-turn record, terse signals); this
|
| 6 |
+
one captures EVERYTHING needed to forensically replay or re-score a
|
| 7 |
+
run after the fact — full obs (including `_raw` and `spatial`), the
|
| 8 |
+
exact briefing the model saw, the system prompt, the literal HTTP
|
| 9 |
+
request body sent to the provider, the literal response (content +
|
| 10 |
+
tool_calls + finish_reason + usage), engine warnings, and a `terminal`
|
| 11 |
+
block on the final turn (outcome, final_obs, wall-clock, tokens).
|
| 12 |
+
|
| 13 |
+
Layout: one JSONL per (model, pack, level, seed, fog_mode) cell at
|
| 14 |
+
|
| 15 |
+
<root>/<pack>__<level>__seed<N>__<fog_mode>.jsonl
|
| 16 |
+
|
| 17 |
+
PNG minimaps go alongside in a sibling dir of the same stem:
|
| 18 |
+
|
| 19 |
+
<root>/<pack>__<level>__seed<N>__<fog_mode>/turn_<N>.png
|
| 20 |
+
|
| 21 |
+
The JSONL line for a turn refs the PNG by relative path (relative to
|
| 22 |
+
the JSONL file's parent). A `terminal:` field on the final line marks
|
| 23 |
+
the episode complete — `scripts/collect_eval_data.py --resume` uses
|
| 24 |
+
that marker to skip cells that already finished cleanly.
|
| 25 |
+
|
| 26 |
+
Why a separate writer (vs extending Playback): the legacy Playback
|
| 27 |
+
format is what `scripts/view_playback.py` reads and what `run_eval.py`
|
| 28 |
+
emits today; rewriting it would invalidate every existing playback
|
| 29 |
+
dir and break the viewer for ~1000 historical episodes. FullPlayback
|
| 30 |
+
runs ALONGSIDE Playback when both are configured; either can be
|
| 31 |
+
disabled independently.
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
from __future__ import annotations
|
| 35 |
+
|
| 36 |
+
import base64
|
| 37 |
+
import json
|
| 38 |
+
import time
|
| 39 |
+
from dataclasses import asdict, is_dataclass
|
| 40 |
+
from pathlib import Path
|
| 41 |
+
from typing import Any
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def _jsonable(o: Any) -> Any:
|
| 45 |
+
"""Recursive serializer matching playback._jsonable but tolerant of
|
| 46 |
+
bytes (base64'd) and tuples (preserved as lists). Bytes are wrapped
|
| 47 |
+
as `{"__b64__": <base64-string>}` so a round-trip recovers them."""
|
| 48 |
+
if isinstance(o, bytes):
|
| 49 |
+
return {"__b64__": base64.b64encode(o).decode("ascii")}
|
| 50 |
+
if is_dataclass(o) and not isinstance(o, type):
|
| 51 |
+
return _jsonable(asdict(o))
|
| 52 |
+
if isinstance(o, dict):
|
| 53 |
+
return {str(k): _jsonable(v) for k, v in o.items()}
|
| 54 |
+
if isinstance(o, (list, tuple)):
|
| 55 |
+
return [_jsonable(v) for v in o]
|
| 56 |
+
if isinstance(o, set):
|
| 57 |
+
return sorted(_jsonable(v) for v in o)
|
| 58 |
+
if isinstance(o, (str, int, float, bool)) or o is None:
|
| 59 |
+
return o
|
| 60 |
+
return repr(o)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _safe(s: str) -> str:
|
| 64 |
+
"""Slug a model id / pack id for path use: keep alnum, `.`, `_`, `-`;
|
| 65 |
+
everything else (especially `/`) becomes `_`."""
|
| 66 |
+
out = []
|
| 67 |
+
for ch in s:
|
| 68 |
+
out.append(ch if (ch.isalnum() or ch in "._-") else "_")
|
| 69 |
+
return "".join(out)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def cell_stem(pack_id: str, level: str, seed: int, fog_mode: str) -> str:
|
| 73 |
+
return f"{_safe(pack_id)}__{_safe(level)}__seed{int(seed)}__{_safe(fog_mode)}"
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
class FullPlayback:
|
| 77 |
+
"""Per-cell audit-ready JSONL + PNG writer.
|
| 78 |
+
|
| 79 |
+
Construct one per (pack, level, seed, fog_mode) cell. Call
|
| 80 |
+
`record_turn(...)` once per model turn (mirroring how the legacy
|
| 81 |
+
Playback is driven from `run_level`); call `finalize(...)` on
|
| 82 |
+
episode end (it emits the `terminal:` field merged into the last
|
| 83 |
+
turn line, NOT a new line — so the file is one-line-per-turn and
|
| 84 |
+
the terminal marker is unambiguous).
|
| 85 |
+
|
| 86 |
+
Concurrency: one cell == one subprocess in the collector, so no
|
| 87 |
+
cross-cell locking is needed. Within a process, this class is NOT
|
| 88 |
+
thread-safe (the eval loop is single-threaded per episode).
|
| 89 |
+
"""
|
| 90 |
+
|
| 91 |
+
def __init__(
|
| 92 |
+
self,
|
| 93 |
+
root: str | Path,
|
| 94 |
+
pack_id: str,
|
| 95 |
+
level: str,
|
| 96 |
+
seed: int,
|
| 97 |
+
fog_mode: str,
|
| 98 |
+
):
|
| 99 |
+
self.root = Path(root)
|
| 100 |
+
self.root.mkdir(parents=True, exist_ok=True)
|
| 101 |
+
self.stem = cell_stem(pack_id, level, seed, fog_mode)
|
| 102 |
+
self.jsonl_path = self.root / f"{self.stem}.jsonl"
|
| 103 |
+
self.png_dir = self.root / self.stem
|
| 104 |
+
self.png_dir.mkdir(parents=True, exist_ok=True)
|
| 105 |
+
# Use a sidecar tmp until finalize, then move atomically over the
|
| 106 |
+
# final path so a `--resume` scan only sees complete files.
|
| 107 |
+
self._tmp_path = self.root / f"{self.stem}.jsonl.partial"
|
| 108 |
+
self._fh = open(self._tmp_path, "w")
|
| 109 |
+
self.pack_id = pack_id
|
| 110 |
+
self.level = level
|
| 111 |
+
self.seed = seed
|
| 112 |
+
self.fog_mode = fog_mode
|
| 113 |
+
self._t0 = time.time()
|
| 114 |
+
# Buffer the last turn line so finalize() can merge `terminal:`
|
| 115 |
+
# into it instead of writing a fresh trailing line (one line ==
|
| 116 |
+
# one turn; the terminal block is a field on the last line).
|
| 117 |
+
self._last_rec: dict | None = None
|
| 118 |
+
# Token accounting across the whole episode (provider-reported
|
| 119 |
+
# usage from each model call); the totals land in `terminal:`.
|
| 120 |
+
self._tokens_in = 0
|
| 121 |
+
self._tokens_out = 0
|
| 122 |
+
# First turn carries the system_prompt; subsequent turns repeat
|
| 123 |
+
# it as `null` to keep the per-turn record uniform but small.
|
| 124 |
+
self._sysp_written = False
|
| 125 |
+
|
| 126 |
+
# ── per-turn ──────────────────────────────────────────────────────
|
| 127 |
+
|
| 128 |
+
def record_turn(
|
| 129 |
+
self,
|
| 130 |
+
*,
|
| 131 |
+
turn: int,
|
| 132 |
+
tick: int | None,
|
| 133 |
+
obs: dict,
|
| 134 |
+
briefing: str,
|
| 135 |
+
system_prompt: str,
|
| 136 |
+
model_request: dict | None,
|
| 137 |
+
model_response: dict | None,
|
| 138 |
+
commands_issued: list,
|
| 139 |
+
engine_warnings: list[str],
|
| 140 |
+
signals: Any,
|
| 141 |
+
minimap_png_b64: str | None = None,
|
| 142 |
+
done: bool = False,
|
| 143 |
+
interrupt: str | None = None,
|
| 144 |
+
extra: dict | None = None,
|
| 145 |
+
) -> None:
|
| 146 |
+
# Flush the previously-buffered line now that we know we're past
|
| 147 |
+
# it (a new turn started, so the prior turn was NOT terminal).
|
| 148 |
+
if self._last_rec is not None:
|
| 149 |
+
self._fh.write(json.dumps(_jsonable(self._last_rec)) + "\n")
|
| 150 |
+
self._fh.flush()
|
| 151 |
+
self._last_rec = None
|
| 152 |
+
|
| 153 |
+
# Track per-call tokens (provider returns them in response.usage)
|
| 154 |
+
u = (model_response or {}).get("usage") or {}
|
| 155 |
+
self._tokens_in += int(u.get("prompt_tokens", 0) or 0)
|
| 156 |
+
self._tokens_out += int(u.get("completion_tokens", 0) or 0)
|
| 157 |
+
|
| 158 |
+
png_rel: str | None = None
|
| 159 |
+
if minimap_png_b64:
|
| 160 |
+
try:
|
| 161 |
+
png_path = self.png_dir / f"turn_{int(turn):03d}.png"
|
| 162 |
+
png_path.write_bytes(base64.b64decode(minimap_png_b64))
|
| 163 |
+
# Relative to the JSONL's parent dir so the file is
|
| 164 |
+
# portable (you can move the run dir without breaking
|
| 165 |
+
# refs).
|
| 166 |
+
png_rel = f"{self.stem}/turn_{int(turn):03d}.png"
|
| 167 |
+
except Exception: # noqa: BLE001 — never break a run on I/O
|
| 168 |
+
png_rel = None
|
| 169 |
+
|
| 170 |
+
rec: dict = {
|
| 171 |
+
"turn": int(turn),
|
| 172 |
+
"tick": tick,
|
| 173 |
+
"interrupt": interrupt,
|
| 174 |
+
"obs": _jsonable(obs),
|
| 175 |
+
"briefing": briefing,
|
| 176 |
+
"system_prompt": system_prompt if not self._sysp_written else None,
|
| 177 |
+
"model_request": _jsonable(model_request) if model_request else None,
|
| 178 |
+
"model_response": _jsonable(model_response) if model_response else None,
|
| 179 |
+
"commands_issued": [repr(c) for c in commands_issued],
|
| 180 |
+
"engine_warnings": list(engine_warnings or []),
|
| 181 |
+
"signals": _jsonable(_signal_snapshot(signals)),
|
| 182 |
+
"minimap_png": png_rel,
|
| 183 |
+
"done": bool(done),
|
| 184 |
+
}
|
| 185 |
+
if extra:
|
| 186 |
+
rec["extra"] = _jsonable(extra)
|
| 187 |
+
self._sysp_written = True
|
| 188 |
+
# Buffer; finalize() merges `terminal:` into this line.
|
| 189 |
+
self._last_rec = rec
|
| 190 |
+
|
| 191 |
+
def finalize(
|
| 192 |
+
self,
|
| 193 |
+
*,
|
| 194 |
+
outcome: str,
|
| 195 |
+
final_obs: dict | None,
|
| 196 |
+
manifest_extra: dict | None = None,
|
| 197 |
+
) -> None:
|
| 198 |
+
"""Stamp the buffered last line with the `terminal:` block,
|
| 199 |
+
flush, and atomically move the partial file over the final
|
| 200 |
+
path so `--resume` sees a fully-complete cell."""
|
| 201 |
+
wall = round(time.time() - self._t0, 3)
|
| 202 |
+
terminal = {
|
| 203 |
+
"outcome": outcome,
|
| 204 |
+
"final_obs": _jsonable(final_obs) if final_obs is not None else None,
|
| 205 |
+
"wall_clock_seconds": wall,
|
| 206 |
+
"total_tokens_in": int(self._tokens_in),
|
| 207 |
+
"total_tokens_out": int(self._tokens_out),
|
| 208 |
+
}
|
| 209 |
+
if manifest_extra:
|
| 210 |
+
terminal["manifest"] = _jsonable(manifest_extra)
|
| 211 |
+
|
| 212 |
+
if self._last_rec is None:
|
| 213 |
+
# Episode produced zero turns (engine crashed on reset, say).
|
| 214 |
+
# Emit a synthetic terminal-only record so `--resume` can
|
| 215 |
+
# still detect "this cell was attempted and completed".
|
| 216 |
+
self._last_rec = {
|
| 217 |
+
"turn": 0,
|
| 218 |
+
"tick": None,
|
| 219 |
+
"interrupt": None,
|
| 220 |
+
"obs": None,
|
| 221 |
+
"briefing": "",
|
| 222 |
+
"system_prompt": None,
|
| 223 |
+
"model_request": None,
|
| 224 |
+
"model_response": None,
|
| 225 |
+
"commands_issued": [],
|
| 226 |
+
"engine_warnings": [],
|
| 227 |
+
"signals": {},
|
| 228 |
+
"minimap_png": None,
|
| 229 |
+
"done": True,
|
| 230 |
+
}
|
| 231 |
+
self._last_rec["terminal"] = terminal
|
| 232 |
+
self._fh.write(json.dumps(_jsonable(self._last_rec)) + "\n")
|
| 233 |
+
self._fh.flush()
|
| 234 |
+
try:
|
| 235 |
+
self._fh.close()
|
| 236 |
+
except Exception: # noqa: BLE001
|
| 237 |
+
pass
|
| 238 |
+
try:
|
| 239 |
+
self._tmp_path.replace(self.jsonl_path)
|
| 240 |
+
except Exception: # noqa: BLE001 — last-ditch fallback
|
| 241 |
+
try:
|
| 242 |
+
self.jsonl_path.write_text(self._tmp_path.read_text())
|
| 243 |
+
except Exception: # noqa: BLE001
|
| 244 |
+
pass
|
| 245 |
+
|
| 246 |
+
def abort(self) -> None:
|
| 247 |
+
"""Close without finalizing. The .partial file stays on disk so
|
| 248 |
+
a post-hoc diagnostic can inspect what was captured before the
|
| 249 |
+
crash; the final .jsonl is NOT created, so `--resume` will
|
| 250 |
+
correctly retry this cell on the next invocation."""
|
| 251 |
+
try:
|
| 252 |
+
if self._last_rec is not None:
|
| 253 |
+
self._fh.write(json.dumps(_jsonable(self._last_rec)) + "\n")
|
| 254 |
+
self._fh.flush()
|
| 255 |
+
self._fh.close()
|
| 256 |
+
except Exception: # noqa: BLE001
|
| 257 |
+
pass
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def _signal_snapshot(signals: Any) -> dict:
|
| 261 |
+
"""Pull every primitive scalar / list off an EpisodeSignals (or
|
| 262 |
+
duck-typed shim) into a JSON-safe dict. Defensive: a missing attr
|
| 263 |
+
is just absent. Mirrors the existing playback shape so downstream
|
| 264 |
+
tools recognise the same field names, but adds a few signals
|
| 265 |
+
(resources, harvesters, tool_violations) that the existing playback
|
| 266 |
+
omits."""
|
| 267 |
+
fields = (
|
| 268 |
+
"game_tick",
|
| 269 |
+
"cash",
|
| 270 |
+
"resources",
|
| 271 |
+
"resource_capacity",
|
| 272 |
+
"power_provided",
|
| 273 |
+
"power_drained",
|
| 274 |
+
"harvesters",
|
| 275 |
+
"explored_percent",
|
| 276 |
+
"units_killed",
|
| 277 |
+
"units_lost",
|
| 278 |
+
"enemies_seen_ids",
|
| 279 |
+
"enemy_buildings_seen_ids",
|
| 280 |
+
"production_items",
|
| 281 |
+
"tool_violations",
|
| 282 |
+
"outcome",
|
| 283 |
+
)
|
| 284 |
+
out: dict[str, Any] = {}
|
| 285 |
+
for f in fields:
|
| 286 |
+
if not hasattr(signals, f):
|
| 287 |
+
continue
|
| 288 |
+
v = getattr(signals, f)
|
| 289 |
+
if isinstance(v, (set, frozenset)):
|
| 290 |
+
v = sorted(_jsonable(x) for x in v)
|
| 291 |
+
out[f] = _jsonable(v)
|
| 292 |
+
# Convenience: counts + computed signals downstream uses heavily.
|
| 293 |
+
if "enemies_seen_ids" in out and isinstance(out["enemies_seen_ids"], list):
|
| 294 |
+
out["enemies_seen_count"] = len(out["enemies_seen_ids"])
|
| 295 |
+
if "enemy_buildings_seen_ids" in out and isinstance(
|
| 296 |
+
out["enemy_buildings_seen_ids"], list
|
| 297 |
+
):
|
| 298 |
+
out["enemy_buildings_seen_count"] = len(out["enemy_buildings_seen_ids"])
|
| 299 |
+
if "cash" in out and "resources" in out:
|
| 300 |
+
try:
|
| 301 |
+
out["economy_value"] = int(out["cash"]) + int(out["resources"])
|
| 302 |
+
except (TypeError, ValueError):
|
| 303 |
+
pass
|
| 304 |
+
return out
|
| 305 |
+
|
| 306 |
+
|
| 307 |
+
def is_complete_cell(jsonl_path: str | Path) -> bool:
|
| 308 |
+
"""True iff `jsonl_path` exists, is non-empty, and the LAST line
|
| 309 |
+
carries a `terminal:` field. The resume scanner uses this so a
|
| 310 |
+
crash mid-cell (partial .jsonl with no terminal) is correctly
|
| 311 |
+
retried, while a cleanly finished cell is correctly skipped.
|
| 312 |
+
|
| 313 |
+
Reads only the file tail (~64KB) — safe to call on thousands of
|
| 314 |
+
cells in a scan."""
|
| 315 |
+
p = Path(jsonl_path)
|
| 316 |
+
if not p.exists() or p.stat().st_size == 0:
|
| 317 |
+
return False
|
| 318 |
+
try:
|
| 319 |
+
# Tail read: open, seek near end, find the last newline-bounded
|
| 320 |
+
# line. JSONL turn records are small (~few KB at most), so 64KB
|
| 321 |
+
# is plenty for the last line of even a long episode.
|
| 322 |
+
with open(p, "rb") as fh:
|
| 323 |
+
fh.seek(0, 2)
|
| 324 |
+
size = fh.tell()
|
| 325 |
+
tail_n = min(size, 65536)
|
| 326 |
+
fh.seek(size - tail_n)
|
| 327 |
+
tail = fh.read().decode("utf-8", errors="replace")
|
| 328 |
+
last = tail.strip().splitlines()[-1] if tail.strip() else ""
|
| 329 |
+
if not last:
|
| 330 |
+
return False
|
| 331 |
+
rec = json.loads(last)
|
| 332 |
+
except (OSError, ValueError):
|
| 333 |
+
return False
|
| 334 |
+
return isinstance(rec, dict) and "terminal" in rec
|
|
@@ -21,8 +21,14 @@ from pathlib import Path
|
|
| 21 |
|
| 22 |
def load_episode(ep_dir: str | Path) -> dict:
|
| 23 |
"""Reassemble one ``seed<N>`` episode folder. Tolerant of a still-
|
| 24 |
-
running episode (missing files become empty).
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
manifest = _read_json(d / "manifest.json", {})
|
| 27 |
messages = _read_json(d / "messages.json", [])
|
| 28 |
turns = []
|
|
@@ -40,10 +46,115 @@ def load_episode(ep_dir: str | Path) -> dict:
|
|
| 40 |
|
| 41 |
|
| 42 |
def find_episodes(root: str | Path) -> list[Path]:
|
| 43 |
-
"""All
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
|
| 49 |
def _read_json(p: Path, default):
|
|
|
|
| 21 |
|
| 22 |
def load_episode(ep_dir: str | Path) -> dict:
|
| 23 |
"""Reassemble one ``seed<N>`` episode folder. Tolerant of a still-
|
| 24 |
+
running episode (missing files become empty).
|
| 25 |
+
|
| 26 |
+
Accepts EITHER a legacy seed dir OR a FullPlayback audit JSONL file;
|
| 27 |
+
a path ending in `.jsonl` dispatches to `load_audit_jsonl`."""
|
| 28 |
+
p = Path(ep_dir)
|
| 29 |
+
if p.is_file() and p.suffix == ".jsonl":
|
| 30 |
+
return load_audit_jsonl(p)
|
| 31 |
+
d = p
|
| 32 |
manifest = _read_json(d / "manifest.json", {})
|
| 33 |
messages = _read_json(d / "messages.json", [])
|
| 34 |
turns = []
|
|
|
|
| 46 |
|
| 47 |
|
| 48 |
def find_episodes(root: str | Path) -> list[Path]:
|
| 49 |
+
"""All episode targets under a playback root.
|
| 50 |
+
|
| 51 |
+
Returns a mix of two shapes the viewer transparently handles:
|
| 52 |
+
* Legacy `.../seed<N>/` dirs (manifest.json + turns.jsonl + …)
|
| 53 |
+
* Audit-format `.../<stem>.jsonl` files written by FullPlayback —
|
| 54 |
+
the loader detects a `.jsonl` path and translates it on the fly.
|
| 55 |
+
"""
|
| 56 |
+
root = Path(root)
|
| 57 |
+
legacy = sorted(
|
| 58 |
+
p.parent for p in root.glob("**/manifest.json")
|
| 59 |
+
) or sorted(root.glob("**/seed*"))
|
| 60 |
+
# Audit-format cells: `<root>/<run_dir>/<pack>__<level>__seedN__fog.jsonl`.
|
| 61 |
+
# Skip the `.partial` half-runs and any sidecar files (start with `_`).
|
| 62 |
+
audit = sorted(
|
| 63 |
+
p for p in root.glob("**/*.jsonl")
|
| 64 |
+
if not p.name.startswith("_")
|
| 65 |
+
and "__seed" in p.name
|
| 66 |
+
and not p.name.endswith(".partial")
|
| 67 |
+
)
|
| 68 |
+
return legacy + audit
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def load_audit_jsonl(jsonl_path: str | Path) -> dict:
|
| 72 |
+
"""Translate a FullPlayback audit JSONL into the same `{dir, manifest,
|
| 73 |
+
turns, messages}` dict shape `load_episode` returns, so the same
|
| 74 |
+
viewer code (`render_streamlit` / downstream loaders) can consume
|
| 75 |
+
either format transparently.
|
| 76 |
+
|
| 77 |
+
- `manifest` is reconstructed from the terminal record's
|
| 78 |
+
`terminal.manifest` block (+ a few top-level fields), preserving
|
| 79 |
+
compatibility with viewers that expect `outcome`, `model`, etc.
|
| 80 |
+
- `turns` mirror the legacy per-turn shape (`turn`, `tick`,
|
| 81 |
+
`commands`, `signals`, `goal`, `minimap_png` path).
|
| 82 |
+
- `messages` is synthesized from the system_prompt + each turn's
|
| 83 |
+
briefing/response, so the viewer's transcript pane still works.
|
| 84 |
+
"""
|
| 85 |
+
p = Path(jsonl_path)
|
| 86 |
+
recs: list[dict] = []
|
| 87 |
+
for line in p.read_text().splitlines():
|
| 88 |
+
line = line.strip()
|
| 89 |
+
if not line:
|
| 90 |
+
continue
|
| 91 |
+
try:
|
| 92 |
+
recs.append(json.loads(line))
|
| 93 |
+
except json.JSONDecodeError:
|
| 94 |
+
continue
|
| 95 |
+
if not recs:
|
| 96 |
+
return {"dir": str(p.parent), "manifest": {}, "turns": [], "messages": []}
|
| 97 |
+
term_block = (recs[-1].get("terminal") or {}) if recs else {}
|
| 98 |
+
manifest: dict = dict(term_block.get("manifest") or {})
|
| 99 |
+
# Surface the audit-only totals at the manifest level so the viewer's
|
| 100 |
+
# "outcome / wall / tokens" header line has them.
|
| 101 |
+
manifest.setdefault("outcome", term_block.get("outcome", "?"))
|
| 102 |
+
manifest.setdefault("wall_clock_seconds", term_block.get("wall_clock_seconds"))
|
| 103 |
+
manifest["total_tokens_in"] = term_block.get("total_tokens_in", 0)
|
| 104 |
+
manifest["total_tokens_out"] = term_block.get("total_tokens_out", 0)
|
| 105 |
+
turns = []
|
| 106 |
+
messages: list[dict] = []
|
| 107 |
+
# System prompt lives on the first turn only.
|
| 108 |
+
sysp = recs[0].get("system_prompt")
|
| 109 |
+
if sysp:
|
| 110 |
+
messages.append({"role": "system", "content": sysp})
|
| 111 |
+
for r in recs:
|
| 112 |
+
# Turn record — translate to legacy keys the viewer recognises.
|
| 113 |
+
png_rel = r.get("minimap_png")
|
| 114 |
+
png_abs = str(p.parent / png_rel) if png_rel else None
|
| 115 |
+
sig = r.get("signals") or {}
|
| 116 |
+
turns.append(
|
| 117 |
+
{
|
| 118 |
+
"turn": r.get("turn"),
|
| 119 |
+
"tick": r.get("tick"),
|
| 120 |
+
"interrupt": r.get("interrupt"),
|
| 121 |
+
"commands": r.get("commands_issued") or [],
|
| 122 |
+
"ascii_minimap": (r.get("obs") or {}).get("minimap", ""),
|
| 123 |
+
"signals": sig,
|
| 124 |
+
"units": (r.get("obs") or {}).get("units_summary", []),
|
| 125 |
+
"enemies": (r.get("obs") or {}).get("enemy_summary", []),
|
| 126 |
+
"goal": {}, # not captured by FullPlayback
|
| 127 |
+
"minimap_png": png_abs,
|
| 128 |
+
}
|
| 129 |
+
)
|
| 130 |
+
if r.get("briefing"):
|
| 131 |
+
messages.append({"role": "user", "content": r["briefing"]})
|
| 132 |
+
resp = r.get("model_response") or {}
|
| 133 |
+
if resp.get("text") or resp.get("tool_calls"):
|
| 134 |
+
messages.append(
|
| 135 |
+
{
|
| 136 |
+
"role": "assistant",
|
| 137 |
+
"content": resp.get("text") or "",
|
| 138 |
+
"tool_calls": [
|
| 139 |
+
{
|
| 140 |
+
"id": f"c{i}",
|
| 141 |
+
"type": "function",
|
| 142 |
+
"function": {
|
| 143 |
+
"name": (tc or {}).get("name", ""),
|
| 144 |
+
"arguments": (tc or {}).get("arguments", {}),
|
| 145 |
+
},
|
| 146 |
+
}
|
| 147 |
+
for i, tc in enumerate(resp.get("tool_calls") or [])
|
| 148 |
+
],
|
| 149 |
+
"reasoning": resp.get("reasoning", ""),
|
| 150 |
+
}
|
| 151 |
+
)
|
| 152 |
+
return {
|
| 153 |
+
"dir": str(p.parent),
|
| 154 |
+
"manifest": manifest,
|
| 155 |
+
"turns": turns,
|
| 156 |
+
"messages": messages,
|
| 157 |
+
}
|
| 158 |
|
| 159 |
|
| 160 |
def _read_json(p: Path, default):
|
|
@@ -145,6 +145,11 @@ class OpenAICompatibleProvider(ChatProvider):
|
|
| 145 |
base=cfg.retry_base_s,
|
| 146 |
cap=cfg.retry_cap_s,
|
| 147 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
@property
|
| 150 |
def cost_meter(self):
|
|
@@ -222,6 +227,34 @@ class OpenAICompatibleProvider(ChatProvider):
|
|
| 222 |
u = reply.usage or {}
|
| 223 |
self._cost.add(u.get("prompt_tokens", 0), u.get("completion_tokens", 0))
|
| 224 |
self._cost.check() # raises BudgetExceeded → evaluate finalizes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
return reply
|
| 226 |
|
| 227 |
def _stream_once(self, url, headers, body) -> ChatReply:
|
|
|
|
| 145 |
base=cfg.retry_base_s,
|
| 146 |
cap=cfg.retry_cap_s,
|
| 147 |
)
|
| 148 |
+
# Audit hook: when set (a list), every successful complete()
|
| 149 |
+
# appends a dict {"request": <body>, "response": <raw>} so the
|
| 150 |
+
# FullPlayback recorder can capture the literal wire payloads.
|
| 151 |
+
# Drained by the caller after each turn. None disables capture.
|
| 152 |
+
self.request_log: list[dict] | None = None
|
| 153 |
|
| 154 |
@property
|
| 155 |
def cost_meter(self):
|
|
|
|
| 227 |
u = reply.usage or {}
|
| 228 |
self._cost.add(u.get("prompt_tokens", 0), u.get("completion_tokens", 0))
|
| 229 |
self._cost.check() # raises BudgetExceeded → evaluate finalizes
|
| 230 |
+
if self.request_log is not None:
|
| 231 |
+
# Audit capture: redact the bearer header (the body is the
|
| 232 |
+
# interesting part) and store the literal request + raw
|
| 233 |
+
# response side-by-side. FullPlayback drains after each turn.
|
| 234 |
+
try:
|
| 235 |
+
self.request_log.append(
|
| 236 |
+
{
|
| 237 |
+
"request": {
|
| 238 |
+
"url": url,
|
| 239 |
+
"body": body,
|
| 240 |
+
},
|
| 241 |
+
"response": {
|
| 242 |
+
"raw": reply.raw,
|
| 243 |
+
"text": reply.text,
|
| 244 |
+
"tool_calls": reply.tool_calls,
|
| 245 |
+
"reasoning": reply.reasoning,
|
| 246 |
+
"usage": dict(reply.usage or {}),
|
| 247 |
+
"finish_reason": (
|
| 248 |
+
(reply.raw.get("choices") or [{}])[0]
|
| 249 |
+
.get("finish_reason")
|
| 250 |
+
if isinstance(reply.raw, dict)
|
| 251 |
+
else None
|
| 252 |
+
),
|
| 253 |
+
},
|
| 254 |
+
}
|
| 255 |
+
)
|
| 256 |
+
except Exception: # noqa: BLE001 — audit must never break a run
|
| 257 |
+
pass
|
| 258 |
return reply
|
| 259 |
|
| 260 |
def _stream_once(self, url, headers, body) -> ChatReply:
|
|
@@ -166,6 +166,7 @@ def evaluate(
|
|
| 166 |
handoff_k: int = 3,
|
| 167 |
handoff_bank: str | Path | None = None,
|
| 168 |
repeats: int = 1,
|
|
|
|
| 169 |
) -> dict:
|
| 170 |
"""Run packs×levels×seeds. If `held_out_seeds` is given, those are
|
| 171 |
run too and tagged split='held_out'; the report adds
|
|
@@ -305,10 +306,18 @@ def evaluate(
|
|
| 305 |
for c in pack.configs
|
| 306 |
]
|
| 307 |
else:
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
for compiled, cell in unit_iter:
|
| 313 |
if not compiled.map_supported:
|
| 314 |
skipped.append(f"{cell} (map not Rust-loadable)")
|
|
@@ -333,6 +342,30 @@ def evaluate(
|
|
| 333 |
seed,
|
| 334 |
)
|
| 335 |
pb.run_id, pb.model = run_id, model
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
ctrl = factory(compiled)
|
| 337 |
if handoff_sweep and ":handoff-" in cell:
|
| 338 |
ctrl, _hnote = _handoff_wrap(
|
|
@@ -340,7 +373,7 @@ def evaluate(
|
|
| 340 |
)
|
| 341 |
else:
|
| 342 |
_hnote = ""
|
| 343 |
-
res = run_level(compiled, ctrl, seed=seed, playback=pb)
|
| 344 |
hstats = getattr(ctrl, "handoff_stats", None)
|
| 345 |
if hstats is not None:
|
| 346 |
hstats = dict(hstats)
|
|
@@ -685,8 +718,22 @@ def main(argv: list[str]) -> int:
|
|
| 685 |
"'wandb/bf16' (no fallback) — premium routing off the free pool",
|
| 686 |
)
|
| 687 |
ap.add_argument("--fog-mode", default="vision",
|
| 688 |
-
choices=[
|
| 689 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
ap.add_argument("--perception-sweep", action="store_true",
|
| 691 |
help="run the 2x2 perception ablation: every "
|
| 692 |
"pack:level expanded into vision/structured x "
|
|
@@ -757,6 +804,7 @@ def main(argv: list[str]) -> int:
|
|
| 757 |
handoff_k=a.handoff_k,
|
| 758 |
handoff_bank=a.handoff_bank,
|
| 759 |
repeats=a.repeats,
|
|
|
|
| 760 |
progress=lambda d, n, rec, c: print(
|
| 761 |
f"[{d}/{n}] {rec['cell']}:{rec['split']}#{rec['seed']} "
|
| 762 |
f"{rec['outcome']} comp={rec['composite']} "
|
|
|
|
| 166 |
handoff_k: int = 3,
|
| 167 |
handoff_bank: str | Path | None = None,
|
| 168 |
repeats: int = 1,
|
| 169 |
+
full_playback_root: str | Path | None = None,
|
| 170 |
) -> dict:
|
| 171 |
"""Run packs×levels×seeds. If `held_out_seeds` is given, those are
|
| 172 |
run too and tagged split='held_out'; the report adds
|
|
|
|
| 306 |
for c in pack.configs
|
| 307 |
]
|
| 308 |
else:
|
| 309 |
+
# Apply the global fog_mode (from ProviderConfig / CLI) so a
|
| 310 |
+
# single-fog run can audit cells in the `image`/`structured`/
|
| 311 |
+
# `-clear` channels (compiled.fog_mode defaults to vision
|
| 312 |
+
# without this lift, which would silently downgrade every
|
| 313 |
+
# cell to the canonical vision-fogged modality).
|
| 314 |
+
_fog = getattr(provider_cfg, "fog_mode", None) if provider_cfg else None
|
| 315 |
+
unit_iter = []
|
| 316 |
+
for lv in levels:
|
| 317 |
+
cl = compile_level(pack, lv)
|
| 318 |
+
if _fog:
|
| 319 |
+
cl.fog_mode = _fog
|
| 320 |
+
unit_iter.append((cl, f"{pack.meta.id}:{lv}"))
|
| 321 |
for compiled, cell in unit_iter:
|
| 322 |
if not compiled.map_supported:
|
| 323 |
skipped.append(f"{cell} (map not Rust-loadable)")
|
|
|
|
| 342 |
seed,
|
| 343 |
)
|
| 344 |
pb.run_id, pb.model = run_id, model
|
| 345 |
+
# Audit-format playback (FullPlayback): one JSONL per cell at the
|
| 346 |
+
# canonical `<pack>__<level>__seed<N>__<fog>.jsonl` path the
|
| 347 |
+
# paper-collection script consumes. Same first-repeat gating as
|
| 348 |
+
# the legacy Playback.
|
| 349 |
+
fpb = None
|
| 350 |
+
if full_playback_root is not None and rep == 0:
|
| 351 |
+
from .full_playback import FullPlayback
|
| 352 |
+
|
| 353 |
+
# Derive (pack_id, level, fog_mode) from the cell. For
|
| 354 |
+
# perception-sweep cells, the cell is `pack:level:mode`; for
|
| 355 |
+
# legacy/configured cells, fall back to compiled fields.
|
| 356 |
+
parts = cell.split(":")
|
| 357 |
+
_pack_id = compiled.pack_id
|
| 358 |
+
_level = compiled.level
|
| 359 |
+
_fog = getattr(compiled, "fog_mode", "vision") or "vision"
|
| 360 |
+
if len(parts) >= 3:
|
| 361 |
+
_fog = parts[-1]
|
| 362 |
+
fpb = FullPlayback(
|
| 363 |
+
Path(full_playback_root) / f"{run_id}__{_safe_model}",
|
| 364 |
+
pack_id=_pack_id,
|
| 365 |
+
level=_level,
|
| 366 |
+
seed=seed,
|
| 367 |
+
fog_mode=_fog,
|
| 368 |
+
)
|
| 369 |
ctrl = factory(compiled)
|
| 370 |
if handoff_sweep and ":handoff-" in cell:
|
| 371 |
ctrl, _hnote = _handoff_wrap(
|
|
|
|
| 373 |
)
|
| 374 |
else:
|
| 375 |
_hnote = ""
|
| 376 |
+
res = run_level(compiled, ctrl, seed=seed, playback=pb, full_playback=fpb)
|
| 377 |
hstats = getattr(ctrl, "handoff_stats", None)
|
| 378 |
if hstats is not None:
|
| 379 |
hstats = dict(hstats)
|
|
|
|
| 718 |
"'wandb/bf16' (no fallback) — premium routing off the free pool",
|
| 719 |
)
|
| 720 |
ap.add_argument("--fog-mode", default="vision",
|
| 721 |
+
choices=[
|
| 722 |
+
"vision", "vision-clear",
|
| 723 |
+
"structured", "structured-clear",
|
| 724 |
+
"image", "image-clear",
|
| 725 |
+
],
|
| 726 |
+
help="spatial channel: PNG minimap (vision), text fog "
|
| 727 |
+
"(structured), or image-primary (image). `-clear` "
|
| 728 |
+
"variants run with no fog of war.")
|
| 729 |
+
ap.add_argument(
|
| 730 |
+
"--full-playback",
|
| 731 |
+
default=None,
|
| 732 |
+
help="audit-format playback dir: one JSONL per cell at "
|
| 733 |
+
"<dir>/<pack>__<level>__seed<N>__<fog>.jsonl with full obs / "
|
| 734 |
+
"request / response / engine warnings. Used by "
|
| 735 |
+
"scripts/collect_eval_data.py for paper-grade data capture.",
|
| 736 |
+
)
|
| 737 |
ap.add_argument("--perception-sweep", action="store_true",
|
| 738 |
help="run the 2x2 perception ablation: every "
|
| 739 |
"pack:level expanded into vision/structured x "
|
|
|
|
| 804 |
handoff_k=a.handoff_k,
|
| 805 |
handoff_bank=a.handoff_bank,
|
| 806 |
repeats=a.repeats,
|
| 807 |
+
full_playback_root=a.full_playback,
|
| 808 |
progress=lambda d, n, rec, c: print(
|
| 809 |
f"[{d}/{n}] {rec['cell']}:{rec['split']}#{rec['seed']} "
|
| 810 |
f"{rec['outcome']} comp={rec['composite']} "
|
|
@@ -55,11 +55,19 @@ base:
|
|
| 55 |
|
| 56 |
levels:
|
| 57 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
description: >
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
overrides: {}
|
| 64 |
win_condition:
|
| 65 |
all_of:
|
|
@@ -78,14 +86,22 @@ levels:
|
|
| 78 |
max_turns: 30
|
| 79 |
|
| 80 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
description: >
|
| 82 |
-
Three
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
bottom-left one — so this needs genuine multi-vector dispatch,
|
| 87 |
-
not one fanned-out march. Enemy infantry contest the two eastern
|
| 88 |
-
lanes; the bottom-left route is clear.
|
| 89 |
overrides:
|
| 90 |
actors:
|
| 91 |
# `stance: 0` (HoldFire) on every agent unit — see the base
|
|
@@ -128,20 +144,28 @@ levels:
|
|
| 128 |
# feedback loop that makes coordinate-blind grounding solvable. A
|
| 129 |
# hard failure attributes to spatial grounding, not extra combat.
|
| 130 |
objective_coords: relative
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
description: >
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
the enemy Power Plant in the SOUTH-WEST (bottom-left), and the
|
| 137 |
-
enemy Ore Refinery in the SOUTH-EAST, before tick 2800, losing
|
| 138 |
-
<=2. Push a group toward each direction and KEEP ADVANCING — do
|
| 139 |
-
not stop at a guessed spot. The instant a unit spots a target
|
| 140 |
-
building you will be interrupted and shown its exact location;
|
| 141 |
-
then converge >=2 units on it. The three lie in three different
|
| 142 |
-
directions; a single eastward column cannot reach the south-west
|
| 143 |
-
one, so this needs genuine multi-vector dispatch. Enemy infantry
|
| 144 |
-
contest the two eastern lanes; the south-west route is clear.
|
| 145 |
overrides:
|
| 146 |
interrupts:
|
| 147 |
# Re-prompt the moment a unit sights a marker building — gives
|
|
|
|
| 55 |
|
| 56 |
levels:
|
| 57 |
easy:
|
| 58 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 59 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 60 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 61 |
+
#
|
| 62 |
+
# Two regions, 6 units. Put >=2 units in EACH region (NE ~110,6 and
|
| 63 |
+
# SE ~110,33) before tick 2400. One direct parallel dispatch makes
|
| 64 |
+
# it (~17-20 turns); touring both with one column does not. Lose if
|
| 65 |
+
# the deadline passes or the force is wiped.
|
| 66 |
description: >
|
| 67 |
+
Split your six tanks into two columns and put at least two units
|
| 68 |
+
into EACH of the north-east and south-east enemy regions within
|
| 69 |
+
about 27 turns. Losing the whole force, or missing the deadline,
|
| 70 |
+
is a loss.
|
| 71 |
overrides: {}
|
| 72 |
win_condition:
|
| 73 |
all_of:
|
|
|
|
| 86 |
max_turns: 30
|
| 87 |
|
| 88 |
medium:
|
| 89 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 90 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 91 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 92 |
+
#
|
| 93 |
+
# Three DISPERSED regions, 8 units, attrition cap. Put >=2 units in
|
| 94 |
+
# EACH of: NE corner (115,6), bottom-left (20,36), SE corner
|
| 95 |
+
# (115,34) before tick 2800, losing <=2. The regions are in three
|
| 96 |
+
# different directions — a single eastward column cannot reach the
|
| 97 |
+
# bottom-left one — so this needs genuine multi-vector dispatch,
|
| 98 |
+
# not one fanned-out march. Enemy infantry contest the two eastern
|
| 99 |
+
# lanes; the bottom-left route is clear.
|
| 100 |
description: >
|
| 101 |
+
Three regions in three different directions (north-east, south-east,
|
| 102 |
+
bottom-left), 8 units. Put at least two units into EACH region
|
| 103 |
+
within about 31 turns, losing no more than two. Enemy infantry
|
| 104 |
+
contest the eastern lanes.
|
|
|
|
|
|
|
|
|
|
| 105 |
overrides:
|
| 106 |
actors:
|
| 107 |
# `stance: 0` (HoldFire) on every agent unit — see the base
|
|
|
|
| 144 |
# feedback loop that makes coordinate-blind grounding solvable. A
|
| 145 |
# hard failure attributes to spatial grounding, not extra combat.
|
| 146 |
objective_coords: relative
|
| 147 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 148 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 149 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 150 |
+
#
|
| 151 |
+
# Three dispersed regions, 8 units, attrition cap — you are NOT
|
| 152 |
+
# given coordinates. Each target region is marked by a specific
|
| 153 |
+
# enemy building, hidden in fog until you scout it. Put >=2 units
|
| 154 |
+
# next to EACH of: the enemy Construction Yard in the NORTH-EAST,
|
| 155 |
+
# the enemy Power Plant in the SOUTH-WEST (bottom-left), and the
|
| 156 |
+
# enemy Ore Refinery in the SOUTH-EAST, before tick 2800, losing
|
| 157 |
+
# <=2. Push a group toward each direction and KEEP ADVANCING — do
|
| 158 |
+
# not stop at a guessed spot. The instant a unit spots a target
|
| 159 |
+
# building you will be interrupted and shown its exact location;
|
| 160 |
+
# then converge >=2 units on it. The three lie in three different
|
| 161 |
+
# directions; a single eastward column cannot reach the south-west
|
| 162 |
+
# one, so this needs genuine multi-vector dispatch. Enemy infantry
|
| 163 |
+
# contest the two eastern lanes; the south-west route is clear.
|
| 164 |
description: >
|
| 165 |
+
No coordinates given. Push columns toward the north-east,
|
| 166 |
+
south-east, and south-west to scout for the enemy Construction
|
| 167 |
+
Yard, Ore Refinery, and Power Plant. Put two units beside each
|
| 168 |
+
within about 31 turns, losing no more than two.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
overrides:
|
| 170 |
interrupts:
|
| 171 |
# Re-prompt the moment a unit sights a marker building — gives
|
|
@@ -46,12 +46,20 @@ levels:
|
|
| 46 |
# ── EASY ── one column, ONE ordered 3-waypoint route, clear lanes,
|
| 47 |
# generous budget. Tests pure "go in the given order, don't idle."
|
| 48 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
description: >
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
the column moving: arrive within the time budget or you lose.
|
| 55 |
overrides:
|
| 56 |
actors:
|
| 57 |
- {type: 2tnk, owner: agent, stance: 0, position: [5, 8], count: 2}
|
|
@@ -80,15 +88,23 @@ levels:
|
|
| 80 |
# execution (finish route N, then route S) overruns the budget —
|
| 81 |
# only a genuine two-column parallel split clears it. Attrition cap.
|
| 82 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
description: >
|
| 84 |
-
TWO
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
Plant) → S3 (far-E SOUTH, enemy Ore Refinery). The two routes
|
| 89 |
-
cross in the middle: split into two columns and run them in
|
| 90 |
-
parallel — doing one fully then the other overruns the clock.
|
| 91 |
-
Lose ≤1 unit; arrive within budget or lose.
|
| 92 |
overrides:
|
| 93 |
actors:
|
| 94 |
# Northern staging cluster
|
|
@@ -141,16 +157,24 @@ levels:
|
|
| 141 |
# Seed picks the staging corner. Strict budget + attrition.
|
| 142 |
hard:
|
| 143 |
objective_coords: relative
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
description: >
|
| 145 |
-
TWO
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
instant a unit sights the marker, revealing it; then move on to
|
| 150 |
-
it and continue the route IN ORDER. Both routes must be completed
|
| 151 |
-
(split into two columns and run them together). Keep advancing —
|
| 152 |
-
idling, skipping, or doing one route then the other overruns the
|
| 153 |
-
clock. Lose ≤1 unit.
|
| 154 |
overrides:
|
| 155 |
# Larger arena for real fog scouting across dispersed enemy bases
|
| 156 |
# (rush-hour-arena 128x40 is too cramped). Generated on demand via
|
|
|
|
| 46 |
# ── EASY ── one column, ONE ordered 3-waypoint route, clear lanes,
|
| 47 |
# generous budget. Tests pure "go in the given order, don't idle."
|
| 48 |
easy:
|
| 49 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 50 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 51 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 52 |
+
#
|
| 53 |
+
# Execute ONE given route IN ORDER: waypoint W1 (mid-south, marked
|
| 54 |
+
# by an enemy Power Plant) → W2 (north, enemy Ore Refinery) → W3 /
|
| 55 |
+
# final (far SE, enemy Construction Yard). You must reach them in
|
| 56 |
+
# that order — rushing straight to the final does NOT count. Keep
|
| 57 |
+
# the column moving: arrive within the time budget or you lose.
|
| 58 |
description: >
|
| 59 |
+
Visit three waypoints IN ORDER: enemy Power Plant (mid-south), then
|
| 60 |
+
Ore Refinery (north), then Construction Yard (far south-east).
|
| 61 |
+
Skipping or reordering does not count. Arrive within about 27
|
| 62 |
+
turns or you lose.
|
|
|
|
| 63 |
overrides:
|
| 64 |
actors:
|
| 65 |
- {type: 2tnk, owner: agent, stance: 0, position: [5, 8], count: 2}
|
|
|
|
| 88 |
# execution (finish route N, then route S) overruns the budget —
|
| 89 |
# only a genuine two-column parallel split clears it. Attrition cap.
|
| 90 |
medium:
|
| 91 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 92 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 93 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 94 |
+
#
|
| 95 |
+
# TWO given routes that must BOTH be completed, each IN ORDER.
|
| 96 |
+
# Route N: N1 (W, enemy Power Plant) → N2 (mid-SOUTH, enemy Ore
|
| 97 |
+
# Refinery) → N3 (far-E NORTH, enemy Construction Yard). Route S:
|
| 98 |
+
# S1 (W-south, enemy Radar Dome) → S2 (mid-NORTH, enemy Power
|
| 99 |
+
# Plant) → S3 (far-E SOUTH, enemy Ore Refinery). The two routes
|
| 100 |
+
# cross in the middle: split into two columns and run them in
|
| 101 |
+
# parallel — doing one fully then the other overruns the clock.
|
| 102 |
+
# Lose ≤1 unit; arrive within budget or lose.
|
| 103 |
description: >
|
| 104 |
+
Run TWO three-waypoint routes IN ORDER, both required. The routes
|
| 105 |
+
cross at mid-map, so split into two columns and run them in
|
| 106 |
+
parallel. Each route is labelled by enemy buildings. Arrive within
|
| 107 |
+
about 34 turns and lose at most one unit.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
overrides:
|
| 109 |
actors:
|
| 110 |
# Northern staging cluster
|
|
|
|
| 157 |
# Seed picks the staging corner. Strict budget + attrition.
|
| 158 |
hard:
|
| 159 |
objective_coords: relative
|
| 160 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 161 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 162 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 163 |
+
#
|
| 164 |
+
# TWO given routes across a large arena, each four ordered
|
| 165 |
+
# waypoints, described ONLY by direction — you are NOT given
|
| 166 |
+
# coordinates. Each waypoint is an enemy building hidden in fog:
|
| 167 |
+
# scout toward the stated direction and you will be interrupted the
|
| 168 |
+
# instant a unit sights the marker, revealing it; then move on to
|
| 169 |
+
# it and continue the route IN ORDER. Both routes must be completed
|
| 170 |
+
# (split into two columns and run them together). Keep advancing —
|
| 171 |
+
# idling, skipping, or doing one route then the other overruns the
|
| 172 |
+
# clock. Lose ≤1 unit.
|
| 173 |
description: >
|
| 174 |
+
TWO four-waypoint routes across a large fogged arena, given only by
|
| 175 |
+
compass direction. Each waypoint is a hidden enemy building. Split
|
| 176 |
+
into two columns and run both routes IN ORDER in parallel. Arrive
|
| 177 |
+
within about 67 turns and lose at most one unit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
overrides:
|
| 179 |
# Larger arena for real fog scouting across dispersed enemy bases
|
| 180 |
# (rush-hour-arena 128x40 is too cramped). Generated on demand via
|
|
@@ -139,14 +139,21 @@ levels:
|
|
| 139 |
# is the point of the easy tier: bare commit-and-kill, no
|
| 140 |
# asymmetry pressure yet.
|
| 141 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
description: >
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
can't damage your tanks meaningfully — driving east and
|
| 147 |
-
finishing them works. You MUST keep at least one tank alive
|
| 148 |
-
AND retain your construction yard (`fact` at 4,20). Before
|
| 149 |
-
tick 5400. Stalling loses on the clock.
|
| 150 |
overrides:
|
| 151 |
actors:
|
| 152 |
# AGENT MEDIUMS — both on the y=20 lane; head-on works on
|
|
@@ -188,22 +195,30 @@ levels:
|
|
| 188 |
# sqrt(16²+6²) ≈ 17 > 16), so the e1s die one at a time without
|
| 189 |
# ever drawing the heavy off post.
|
| 190 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
description: >
|
| 192 |
-
Two medium tanks
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
The heavy's cannon out-DPSs your medium pair at close range —
|
| 197 |
-
a head-on push along y=20 fixes you against the infantry wall
|
| 198 |
-
long enough for the heavy to lunge into range and finish you.
|
| 199 |
-
The only winning play is to stage OFF-AXIS (e.g. on the north
|
| 200 |
-
corridor y=10), approach the infantry from a flank cell that
|
| 201 |
-
is within your tank's gun range of an infantryman but OUTSIDE
|
| 202 |
-
the heavy's aggro radius, pick off the infantry one at a time,
|
| 203 |
-
and retreat past the heavy's leash any time it lunges. Keep
|
| 204 |
-
at least one tank alive AND retain your construction yard
|
| 205 |
-
(`fact` at 4,20). Before tick 5400. Stall, head-on charge,
|
| 206 |
-
and brute attack_move east all LOSE.
|
| 207 |
overrides:
|
| 208 |
actors:
|
| 209 |
# AGENT MEDIUMS — stage OFF-AXIS on the north corridor
|
|
@@ -249,20 +264,28 @@ levels:
|
|
| 249 |
# — a sluggish kite cadence runs the clock; the asymmetric play
|
| 250 |
# has to be efficient.
|
| 251 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
description: >
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
(around x=74) and 1× HEAVY tank (3tnk) at the east face
|
| 258 |
-
(90,20). Whichever corridor you stage on, the working flank
|
| 259 |
-
attack is on YOUR side of the cluster (north flank from a
|
| 260 |
-
north spawn; south flank from a south spawn). Head-on along
|
| 261 |
-
y=20 still LOSES. Stage off-axis, approach the infantry on
|
| 262 |
-
the flank that keeps you outside the heavy's aggro envelope,
|
| 263 |
-
pick the infantry off, retreat past the leash any time the
|
| 264 |
-
heavy lunges. Keep at least one tank alive AND retain your
|
| 265 |
-
construction yard (`fact` at 4,20). Before tick 4500.
|
| 266 |
overrides:
|
| 267 |
actors:
|
| 268 |
# spawn_point 0 — NORTH staging corridor (y=12). Natural
|
|
|
|
| 139 |
# is the point of the easy tier: bare commit-and-kill, no
|
| 140 |
# asymmetry pressure yet.
|
| 141 |
easy:
|
| 142 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 143 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 144 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 145 |
+
#
|
| 146 |
+
# Two of your medium tanks (2tnk) at the west of the map (x≈8,
|
| 147 |
+
# y=20) must kill TWO enemy rifle infantry (e1) holding post at
|
| 148 |
+
# the east-centre cluster (around x=78, y=20). The infantry
|
| 149 |
+
# can't damage your tanks meaningfully — driving east and
|
| 150 |
+
# finishing them works. You MUST keep at least one tank alive
|
| 151 |
+
# AND retain your construction yard (`fact` at 4,20). Before
|
| 152 |
+
# tick 5400. Stalling loses on the clock.
|
| 153 |
description: >
|
| 154 |
+
Your two medium tanks must kill two enemy rifle infantry at the
|
| 155 |
+
east-centre cluster within about 60 turns. Keep at least one tank
|
| 156 |
+
alive and keep your construction yard standing.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
overrides:
|
| 158 |
actors:
|
| 159 |
# AGENT MEDIUMS — both on the y=20 lane; head-on works on
|
|
|
|
| 195 |
# sqrt(16²+6²) ≈ 17 > 16), so the e1s die one at a time without
|
| 196 |
# ever drawing the heavy off post.
|
| 197 |
medium:
|
| 198 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 199 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 200 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 201 |
+
#
|
| 202 |
+
# Two medium tanks (2tnk) at the west of the map must kill FOUR
|
| 203 |
+
# enemy rifle infantry (e1) that form a wall on the west face of
|
| 204 |
+
# the east-centre cluster (around x=74, y=18..22), behind which
|
| 205 |
+
# a HEAVY enemy tank (3tnk) holds post on the east face (90,20).
|
| 206 |
+
# The heavy's cannon out-DPSs your medium pair at close range —
|
| 207 |
+
# a head-on push along y=20 fixes you against the infantry wall
|
| 208 |
+
# long enough for the heavy to lunge into range and finish you.
|
| 209 |
+
# The only winning play is to stage OFF-AXIS (e.g. on the north
|
| 210 |
+
# corridor y=10), approach the infantry from a flank cell that
|
| 211 |
+
# is within your tank's gun range of an infantryman but OUTSIDE
|
| 212 |
+
# the heavy's aggro radius, pick off the infantry one at a time,
|
| 213 |
+
# and retreat past the heavy's leash any time it lunges. Keep
|
| 214 |
+
# at least one tank alive AND retain your construction yard
|
| 215 |
+
# (`fact` at 4,20). Before tick 5400. Stall, head-on charge,
|
| 216 |
+
# and brute attack_move east all LOSE.
|
| 217 |
description: >
|
| 218 |
+
Two medium tanks must kill four enemy rifle infantry walling the
|
| 219 |
+
east-centre cluster while a heavy enemy tank holds post just
|
| 220 |
+
behind them. The heavy out-trades you head-on. Keep one tank
|
| 221 |
+
alive, keep your construction yard, finish within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
overrides:
|
| 223 |
actors:
|
| 224 |
# AGENT MEDIUMS — stage OFF-AXIS on the north corridor
|
|
|
|
| 264 |
# — a sluggish kite cadence runs the clock; the asymmetric play
|
| 265 |
# has to be efficient.
|
| 266 |
hard:
|
| 267 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 268 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 269 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 270 |
+
#
|
| 271 |
+
# Two medium tanks (2tnk) stage at one of two west-of-map
|
| 272 |
+
# corridors (NORTH y=12 OR SOUTH y=28, chosen by seed —
|
| 273 |
+
# anti-memorisation). The garrison is identical to medium —
|
| 274 |
+
# 4× rifle infantry (e1) walling the west face of the cluster
|
| 275 |
+
# (around x=74) and 1× HEAVY tank (3tnk) at the east face
|
| 276 |
+
# (90,20). Whichever corridor you stage on, the working flank
|
| 277 |
+
# attack is on YOUR side of the cluster (north flank from a
|
| 278 |
+
# north spawn; south flank from a south spawn). Head-on along
|
| 279 |
+
# y=20 still LOSES. Stage off-axis, approach the infantry on
|
| 280 |
+
# the flank that keeps you outside the heavy's aggro envelope,
|
| 281 |
+
# pick the infantry off, retreat past the leash any time the
|
| 282 |
+
# heavy lunges. Keep at least one tank alive AND retain your
|
| 283 |
+
# construction yard (`fact` at 4,20). Before tick 4500.
|
| 284 |
description: >
|
| 285 |
+
Same composition as medium but a tighter deadline (about 50
|
| 286 |
+
turns), and your two tanks stage in either the north or south
|
| 287 |
+
corridor (seed picks). Kill four rifle infantry without losing
|
| 288 |
+
both tanks or your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
overrides:
|
| 290 |
actors:
|
| 291 |
# spawn_point 0 — NORTH staging corridor (y=12). Natural
|
|
@@ -166,18 +166,25 @@ levels:
|
|
| 166 |
# Wrong-counter (8× e3) cost-per-effect wastes on soft infantry.
|
| 167 |
# Stall: kill bar (6) never met → after_ticks LOSS.
|
| 168 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
description: >
|
| 170 |
-
Cash $2550
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
factory, service depot, 2 scout jeeps) — all production
|
| 174 |
-
queues are online from turn 1. Scout the enemy with a jeep,
|
| 175 |
-
read the composition, then commit the whole $2550 to the
|
| 176 |
-
matching counter (3× medium tanks 2tnk = $2550 walks through
|
| 177 |
-
a rifle swarm; mass rockets are anti-armour ordnance and
|
| 178 |
-
waste cost-per-effect on soft targets). Win when 6 enemy
|
| 179 |
-
units are killed AND your construction yard still stands,
|
| 180 |
-
before tick 5400. Stalling and wrong-counter both LOSE.
|
| 181 |
overrides:
|
| 182 |
actors:
|
| 183 |
- {type: fact, owner: agent, stance: 0, position: [10, 20]}
|
|
@@ -220,18 +227,26 @@ levels:
|
|
| 220 |
# ground-truth, and a play that scouts must DO so before
|
| 221 |
# committing.
|
| 222 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
description: >
|
| 224 |
-
Cash $2550
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
refinery, power, barracks, war factory, and service depot are
|
| 229 |
-
all online from turn 1. Once you've read the enemy, commit
|
| 230 |
-
the WHOLE $2550 to the matching counter (3× 2tnk medium tanks
|
| 231 |
-
walks through a rifle swarm; mass rockets are anti-armour and
|
| 232 |
-
waste cost-per-effect; mass own rifles is a 1:1 trade with no
|
| 233 |
-
positional advantage). Win when 8 enemy units are killed AND
|
| 234 |
-
your construction yard still stands, before tick 5400.
|
| 235 |
overrides:
|
| 236 |
actors:
|
| 237 |
- {type: fact, owner: agent, stance: 0, position: [10, 20]}
|
|
@@ -295,20 +310,29 @@ levels:
|
|
| 295 |
# escorts = 5, the e3 cluster has 5 rocket soldiers) while a
|
| 296 |
# wrong-counter play stalls below it.
|
| 297 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 298 |
description: >
|
| 299 |
-
Cash $2550
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
column (3tnk), or an anti-armour rocket cluster (e3). Each
|
| 305 |
-
archetype demands a DIFFERENT counter: tanks (2tnk) shred
|
| 306 |
-
rifles; rockets (e3) shred heavy armour; mass rifles (e1)
|
| 307 |
-
shred rockets (e3 are anti-armour, weak vs soft mass).
|
| 308 |
-
Scout with a jeep to identify the composition BEFORE
|
| 309 |
-
committing the budget — a pre-committed single build LOSES
|
| 310 |
-
on at least one seed. Win when 5 enemy units are killed AND
|
| 311 |
-
your construction yard still stands, before tick 5400.
|
| 312 |
overrides:
|
| 313 |
actors:
|
| 314 |
# ── AGENT BASE (no spawn_point — identical every seed) ──
|
|
|
|
| 166 |
# Wrong-counter (8× e3) cost-per-effect wastes on soft infantry.
|
| 167 |
# Stall: kill bar (6) never met → after_ticks LOSS.
|
| 168 |
easy:
|
| 169 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 170 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 171 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 172 |
+
#
|
| 173 |
+
# Cash $2550. The enemy is a small rifle-infantry swarm (8× e1)
|
| 174 |
+
# entrenched at the centre of the map. You start with a full
|
| 175 |
+
# base (construction yard, refinery, power, barracks, war
|
| 176 |
+
# factory, service depot, 2 scout jeeps) — all production
|
| 177 |
+
# queues are online from turn 1. Scout the enemy with a jeep,
|
| 178 |
+
# read the composition, then commit the whole $2550 to the
|
| 179 |
+
# matching counter (3× medium tanks 2tnk = $2550 walks through
|
| 180 |
+
# a rifle swarm; mass rockets are anti-armour ordnance and
|
| 181 |
+
# waste cost-per-effect on soft targets). Win when 6 enemy
|
| 182 |
+
# units are killed AND your construction yard still stands,
|
| 183 |
+
# before tick 5400. Stalling and wrong-counter both LOSE.
|
| 184 |
description: >
|
| 185 |
+
Cash $2550, full base online. Enemy is a rifle-infantry swarm at
|
| 186 |
+
centre-east. Pick the matching counter and kill six enemy units
|
| 187 |
+
within about 60 turns, keeping your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
overrides:
|
| 189 |
actors:
|
| 190 |
- {type: fact, owner: agent, stance: 0, position: [10, 20]}
|
|
|
|
| 227 |
# ground-truth, and a play that scouts must DO so before
|
| 228 |
# committing.
|
| 229 |
medium:
|
| 230 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 231 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 232 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 233 |
+
#
|
| 234 |
+
# Cash $2550. The enemy holds a centre garrison (~12 rifle
|
| 235 |
+
# infantry) on the central lane; their composition is FOGGED
|
| 236 |
+
# — scout with one of the starter jeeps to verify the threat
|
| 237 |
+
# profile BEFORE committing the budget. Your construction yard,
|
| 238 |
+
# refinery, power, barracks, war factory, and service depot are
|
| 239 |
+
# all online from turn 1. Once you've read the enemy, commit
|
| 240 |
+
# the WHOLE $2550 to the matching counter (3× 2tnk medium tanks
|
| 241 |
+
# walks through a rifle swarm; mass rockets are anti-armour and
|
| 242 |
+
# waste cost-per-effect; mass own rifles is a 1:1 trade with no
|
| 243 |
+
# positional advantage). Win when 8 enemy units are killed AND
|
| 244 |
+
# your construction yard still stands, before tick 5400.
|
| 245 |
description: >
|
| 246 |
+
Cash $2550, full base online. A centre garrison sits in fog —
|
| 247 |
+
scout with a jeep first, then commit the budget to the matching
|
| 248 |
+
counter. Kill eight enemy units within about 60 turns, keeping
|
| 249 |
+
your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 250 |
overrides:
|
| 251 |
actors:
|
| 252 |
- {type: fact, owner: agent, stance: 0, position: [10, 20]}
|
|
|
|
| 310 |
# escorts = 5, the e3 cluster has 5 rocket soldiers) while a
|
| 311 |
# wrong-counter play stalls below it.
|
| 312 |
hard:
|
| 313 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 314 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 315 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 316 |
+
#
|
| 317 |
+
# Cash $2550. Your base is fixed at the west (construction
|
| 318 |
+
# yard, refinery, power, barracks, war factory, service depot,
|
| 319 |
+
# 2 scout jeeps) — full production from turn 1. The enemy
|
| 320 |
+
# garrison at the centre-east of the map rotates ARCHETYPE
|
| 321 |
+
# across seeds: an entrenched rifle swarm (e1), a heavy tank
|
| 322 |
+
# column (3tnk), or an anti-armour rocket cluster (e3). Each
|
| 323 |
+
# archetype demands a DIFFERENT counter: tanks (2tnk) shred
|
| 324 |
+
# rifles; rockets (e3) shred heavy armour; mass rifles (e1)
|
| 325 |
+
# shred rockets (e3 are anti-armour, weak vs soft mass).
|
| 326 |
+
# Scout with a jeep to identify the composition BEFORE
|
| 327 |
+
# committing the budget — a pre-committed single build LOSES
|
| 328 |
+
# on at least one seed. Win when 5 enemy units are killed AND
|
| 329 |
+
# your construction yard still stands, before tick 5400.
|
| 330 |
description: >
|
| 331 |
+
Cash $2550, full base online. The centre-east enemy archetype
|
| 332 |
+
rotates per seed (rifle swarm, heavy tank column, or rocket
|
| 333 |
+
cluster). Scout first, then commit the budget to the matching
|
| 334 |
+
counter. Kill five enemy units within about 60 turns, keeping
|
| 335 |
+
your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
overrides:
|
| 337 |
actors:
|
| 338 |
# ── AGENT BASE (no spawn_point — identical every seed) ──
|
|
@@ -89,11 +89,18 @@ levels:
|
|
| 89 |
own_units_gte: 1
|
| 90 |
max_turns: 70
|
| 91 |
hard:
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
overrides:
|
| 98 |
actors:
|
| 99 |
- type: 2tnk
|
|
|
|
| 89 |
own_units_gte: 1
|
| 90 |
max_turns: 70
|
| 91 |
hard:
|
| 92 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 93 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 94 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 95 |
+
#
|
| 96 |
+
# Rung 3 — 3 tanks vs 8, loss-capped, and the outnumbered force
|
| 97 |
+
# starts from a seed-chosen corner (two spawn_point groups → start
|
| 98 |
+
# axis varies by seed, so a memorised kite line can't generalise).
|
| 99 |
+
# Enemy is mid-map beyond initial sight: engage selection under fog.
|
| 100 |
+
description: >
|
| 101 |
+
Outnumbered three tanks vs eight mixed enemies under fog. Start
|
| 102 |
+
corner varies by seed. Kill eight, losing at most two, within
|
| 103 |
+
about 89 turns.
|
| 104 |
overrides:
|
| 105 |
actors:
|
| 106 |
- type: 2tnk
|
|
@@ -62,13 +62,21 @@ levels:
|
|
| 62 |
# leading the hunters off with the jeeps clears the way. Generous
|
| 63 |
# clock.
|
| 64 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
description: >
|
| 66 |
-
A hunting
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
a separate vector to pull the hunters off, then run the tanks
|
| 71 |
-
through. Idling or never committing loses on the clock.
|
| 72 |
overrides: {}
|
| 73 |
win_condition:
|
| 74 |
all_of:
|
|
@@ -83,10 +91,16 @@ levels:
|
|
| 83 |
# ── MEDIUM ── +1 controlled variable: a heavier anti-armor picket
|
| 84 |
# (more e3) so a head-on push is decisively fatal; tighter clock.
|
| 85 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
description: >
|
| 87 |
-
Heavier rocket-infantry picket
|
| 88 |
-
|
| 89 |
-
tanks on the objective before the (tighter) deadline.
|
| 90 |
overrides:
|
| 91 |
actors:
|
| 92 |
- {type: 2tnk, owner: agent, position: [6, 20], stance: 1, count: 3}
|
|
@@ -115,12 +129,19 @@ levels:
|
|
| 115 |
# be memorised; strongest picket; strict attrition cap on top (the
|
| 116 |
# main body must arrive nearly whole — only the bait may be spent).
|
| 117 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
description: >
|
| 119 |
-
Strongest hunting picket
|
| 120 |
-
latitude
|
| 121 |
-
|
| 122 |
-
units (only the two bait jeeps may be spent — burning armour
|
| 123 |
-
fails) before the tight deadline.
|
| 124 |
overrides:
|
| 125 |
actors:
|
| 126 |
# spawn_point 0 — northern staging
|
|
|
|
| 62 |
# leading the hunters off with the jeeps clears the way. Generous
|
| 63 |
# clock.
|
| 64 |
easy:
|
| 65 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 66 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 67 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 68 |
+
#
|
| 69 |
+
# A hunting picket (rocket infantry + riflemen) blocks the lane to
|
| 70 |
+
# the objective and chases your nearest unit. Get THREE tanks to
|
| 71 |
+
# the objective (far east). Driving the column straight in gets it
|
| 72 |
+
# shot apart before three arrive; send the fast jeeps in as bait on
|
| 73 |
+
# a separate vector to pull the hunters off, then run the tanks
|
| 74 |
+
# through. Idling or never committing loses on the clock.
|
| 75 |
description: >
|
| 76 |
+
A hunting rocket-and-rifle picket blocks the corridor to the far
|
| 77 |
+
east objective. Get three tanks to the objective within about 65
|
| 78 |
+
turns. The picket chases the nearest unit, so an unsupported
|
| 79 |
+
head-on push is fatal.
|
|
|
|
|
|
|
| 80 |
overrides: {}
|
| 81 |
win_condition:
|
| 82 |
all_of:
|
|
|
|
| 91 |
# ── MEDIUM ── +1 controlled variable: a heavier anti-armor picket
|
| 92 |
# (more e3) so a head-on push is decisively fatal; tighter clock.
|
| 93 |
medium:
|
| 94 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 95 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 96 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 97 |
+
#
|
| 98 |
+
# Heavier rocket-infantry picket — a head-on push is now decisively
|
| 99 |
+
# fatal. Same task: divert the hunters with the bait, land THREE
|
| 100 |
+
# tanks on the objective before the (tighter) deadline.
|
| 101 |
description: >
|
| 102 |
+
Heavier rocket-infantry picket. Land three tanks on the far east
|
| 103 |
+
objective within about 75 turns.
|
|
|
|
| 104 |
overrides:
|
| 105 |
actors:
|
| 106 |
- {type: 2tnk, owner: agent, position: [6, 20], stance: 1, count: 3}
|
|
|
|
| 129 |
# be memorised; strongest picket; strict attrition cap on top (the
|
| 130 |
# main body must arrive nearly whole — only the bait may be spent).
|
| 131 |
hard:
|
| 132 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 133 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 134 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 135 |
+
#
|
| 136 |
+
# Strongest hunting picket; the force stages from a seed-chosen
|
| 137 |
+
# latitude (the decoy line that works varies by seed, so it can't
|
| 138 |
+
# be memorised). Land THREE tanks on the objective AND lose ≤2
|
| 139 |
+
# units (only the two bait jeeps may be spent — burning armour
|
| 140 |
+
# fails) before the tight deadline.
|
| 141 |
description: >
|
| 142 |
+
Strongest hunting picket. The force stages from a seed-chosen
|
| 143 |
+
latitude. Land three tanks on the far east objective, losing at
|
| 144 |
+
most two units, within about 82 turns.
|
|
|
|
|
|
|
| 145 |
overrides:
|
| 146 |
actors:
|
| 147 |
# spawn_point 0 — northern staging
|
|
@@ -67,14 +67,21 @@ levels:
|
|
| 67 |
# flank route around the wall's east end lands the force. Generous
|
| 68 |
# clock. Loss-cap of 1 (a single clipped tank is forgivable here).
|
| 69 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
description: >
|
| 71 |
-
A
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
Driving the column straight in loses it in a turn; go the long way
|
| 75 |
-
— climb to the open flank, run east PAST the end of the wall, then
|
| 76 |
-
turn down to the objective. Idling never commits and loses on the
|
| 77 |
-
clock.
|
| 78 |
overrides: {}
|
| 79 |
win_condition:
|
| 80 |
all_of:
|
|
@@ -92,12 +99,18 @@ levels:
|
|
| 92 |
# east, x=26..86) so the survivable flank route is longer and the
|
| 93 |
# detour costs more turns before it pays off; tighter clock; zero-loss.
|
| 94 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
description: >
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
task: ignore the lethal short lane entirely, take the flank route
|
| 99 |
-
around the (longer) wall's end, land THREE tanks on the objective
|
| 100 |
-
before the tighter deadline.
|
| 101 |
overrides:
|
| 102 |
actors:
|
| 103 |
- {type: 1tnk, owner: agent, position: [6, 20], stance: 1, count: 3}
|
|
@@ -138,13 +151,21 @@ levels:
|
|
| 138 |
# can't be memorised. Strongest/longest wall; strict zero-loss; every
|
| 139 |
# surviving unit must arrive (all_units_in_region) and ≥3 must.
|
| 140 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
description: >
|
| 142 |
-
Strongest
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
surviving tank, ≥3) onto the objective with ZERO losses, via the
|
| 147 |
-
long way around the wall's end, before the tight deadline.
|
| 148 |
overrides:
|
| 149 |
actors:
|
| 150 |
# spawn_point 0 — northern staging
|
|
|
|
| 67 |
# flank route around the wall's east end lands the force. Generous
|
| 68 |
# clock. Loss-cap of 1 (a single clipped tank is forgivable here).
|
| 69 |
easy:
|
| 70 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 71 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 72 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 73 |
+
#
|
| 74 |
+
# A leashed rocket-infantry wall blocks the direct lane east to the
|
| 75 |
+
# objective and shreds anything that tries to cross it. Get THREE
|
| 76 |
+
# tanks to the objective (far east, marked by the enemy structure).
|
| 77 |
+
# Driving the column straight in loses it in a turn; go the long way
|
| 78 |
+
# — climb to the open flank, run east PAST the end of the wall, then
|
| 79 |
+
# turn down to the objective. Idling never commits and loses on the
|
| 80 |
+
# clock.
|
| 81 |
description: >
|
| 82 |
+
A rocket-infantry wall blocks the direct lane east. Get three
|
| 83 |
+
tanks to the far east objective within about 59 turns, losing at
|
| 84 |
+
most one. Crossing the wall head-on is fatal.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
overrides: {}
|
| 86 |
win_condition:
|
| 87 |
all_of:
|
|
|
|
| 99 |
# east, x=26..86) so the survivable flank route is longer and the
|
| 100 |
# detour costs more turns before it pays off; tighter clock; zero-loss.
|
| 101 |
medium:
|
| 102 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 103 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 104 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 105 |
+
#
|
| 106 |
+
# The guard wall now extends much farther east — the long way round
|
| 107 |
+
# is longer and costlier, and a single clipped tank now fails. Same
|
| 108 |
+
# task: ignore the lethal short lane entirely, take the flank route
|
| 109 |
+
# around the (longer) wall's end, land THREE tanks on the objective
|
| 110 |
+
# before the tighter deadline.
|
| 111 |
description: >
|
| 112 |
+
Longer rocket-infantry wall. Get three tanks to the far east
|
| 113 |
+
objective within about 65 turns with ZERO losses.
|
|
|
|
|
|
|
|
|
|
| 114 |
overrides:
|
| 115 |
actors:
|
| 116 |
- {type: 1tnk, owner: agent, position: [6, 20], stance: 1, count: 3}
|
|
|
|
| 151 |
# can't be memorised. Strongest/longest wall; strict zero-loss; every
|
| 152 |
# surviving unit must arrive (all_units_in_region) and ≥3 must.
|
| 153 |
hard:
|
| 154 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 155 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 156 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 157 |
+
#
|
| 158 |
+
# Strongest, longest wall; the force stages from a seed-chosen
|
| 159 |
+
# latitude (north or south of the wall), so the length and shape of
|
| 160 |
+
# the long way round varies by seed and can't be memorised. The
|
| 161 |
+
# short lane is lethal from either start. Get the WHOLE force (every
|
| 162 |
+
# surviving tank, ≥3) onto the objective with ZERO losses, via the
|
| 163 |
+
# long way around the wall's end, before the tight deadline.
|
| 164 |
description: >
|
| 165 |
+
Strongest wall. Stage from a seed-chosen latitude (north or south
|
| 166 |
+
of the wall). Land the WHOLE surviving force (at least three
|
| 167 |
+
tanks) on the far east objective with ZERO losses, within about
|
| 168 |
+
69 turns.
|
|
|
|
|
|
|
| 169 |
overrides:
|
| 170 |
actors:
|
| 171 |
# spawn_point 0 — northern staging
|
|
@@ -85,16 +85,24 @@ levels:
|
|
| 85 |
# 2; burning a tank fails). Idling never commits and loses on the
|
| 86 |
# clock.
|
| 87 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
description: >
|
| 89 |
-
A
|
| 90 |
-
objective
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
into the wall and it is destroyed; send the fast jeeps in close
|
| 94 |
-
on a separate vector so a segment of the wall lunges off post
|
| 95 |
-
after them, then run the tanks through the open slot before it
|
| 96 |
-
snaps back. Only the two bait jeeps may be spent — burning a tank
|
| 97 |
-
(≥3 lost) fails. Idling never commits and loses on the clock.
|
| 98 |
overrides: {}
|
| 99 |
win_condition:
|
| 100 |
all_of:
|
|
@@ -113,12 +121,18 @@ levels:
|
|
| 113 |
# segment off; tighter clock. Same loss cap of 2 (only the two bait
|
| 114 |
# jeeps may be spent — burning armour fails).
|
| 115 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
description: >
|
| 117 |
-
Denser rocket-infantry wall
|
| 118 |
-
|
| 119 |
-
task: lure a segment off post with the jeeps on a divergent
|
| 120 |
-
vector, run THREE tanks through the open slot to the objective
|
| 121 |
-
before the (tighter) deadline, losing only the two bait jeeps.
|
| 122 |
overrides:
|
| 123 |
actors:
|
| 124 |
- {type: 2tnk, owner: agent, position: [6, 20], stance: 1, count: 3}
|
|
@@ -151,13 +165,20 @@ levels:
|
|
| 151 |
# the lure line can't be memorised. Densest wall; strict loss cap of
|
| 152 |
# 2 (only the two bait jeeps may be spent — burning armour fails).
|
| 153 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
description: >
|
| 155 |
-
Densest guard wall
|
| 156 |
-
(north or south)
|
| 157 |
-
|
| 158 |
-
off post with the jeeps, then run THREE tanks through the open
|
| 159 |
-
slot to the objective AND lose ≤2 units (only the two bait jeeps
|
| 160 |
-
may be spent — burning armour fails) before the tight deadline.
|
| 161 |
overrides:
|
| 162 |
actors:
|
| 163 |
# spawn_point 0 — northern staging (in-bounds, y=10/14)
|
|
|
|
| 85 |
# 2; burning a tank fails). Idling never commits and loses on the
|
| 86 |
# clock.
|
| 87 |
easy:
|
| 88 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 89 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 90 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 91 |
+
#
|
| 92 |
+
# A strong rocket-infantry guard wall blocks the one lane to the
|
| 93 |
+
# objective (far east, marked by the enemy structure) and snaps
|
| 94 |
+
# straight back to it the instant nothing threatens it. Get THREE
|
| 95 |
+
# tanks to the objective. Driving the column straight in runs it
|
| 96 |
+
# into the wall and it is destroyed; send the fast jeeps in close
|
| 97 |
+
# on a separate vector so a segment of the wall lunges off post
|
| 98 |
+
# after them, then run the tanks through the open slot before it
|
| 99 |
+
# snaps back. Only the two bait jeeps may be spent — burning a tank
|
| 100 |
+
# (≥3 lost) fails. Idling never commits and loses on the clock.
|
| 101 |
description: >
|
| 102 |
+
A leashed rocket-infantry wall blocks the lane to the far east
|
| 103 |
+
objective; each guard lunges at nearby foes then snaps back. Get
|
| 104 |
+
three tanks to the objective within about 65 turns, losing at
|
| 105 |
+
most two units.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
overrides: {}
|
| 107 |
win_condition:
|
| 108 |
all_of:
|
|
|
|
| 121 |
# segment off; tighter clock. Same loss cap of 2 (only the two bait
|
| 122 |
# jeeps may be spent — burning armour fails).
|
| 123 |
medium:
|
| 124 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 125 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 126 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 127 |
+
#
|
| 128 |
+
# Denser rocket-infantry wall — a head-on push is now decisively
|
| 129 |
+
# fatal and the bait must pull a wider segment off the lane. Same
|
| 130 |
+
# task: lure a segment off post with the jeeps on a divergent
|
| 131 |
+
# vector, run THREE tanks through the open slot to the objective
|
| 132 |
+
# before the (tighter) deadline, losing only the two bait jeeps.
|
| 133 |
description: >
|
| 134 |
+
Denser rocket-infantry wall. Get three tanks to the far east
|
| 135 |
+
objective within about 75 turns, losing at most two units.
|
|
|
|
|
|
|
|
|
|
| 136 |
overrides:
|
| 137 |
actors:
|
| 138 |
- {type: 2tnk, owner: agent, position: [6, 20], stance: 1, count: 3}
|
|
|
|
| 165 |
# the lure line can't be memorised. Densest wall; strict loss cap of
|
| 166 |
# 2 (only the two bait jeeps may be spent — burning armour fails).
|
| 167 |
hard:
|
| 168 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 169 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 170 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 171 |
+
#
|
| 172 |
+
# Densest guard wall; the force stages from a seed-chosen latitude
|
| 173 |
+
# (north or south), so the bait vector and the slot the main body
|
| 174 |
+
# runs through vary by seed and can't be memorised. Lure a segment
|
| 175 |
+
# off post with the jeeps, then run THREE tanks through the open
|
| 176 |
+
# slot to the objective AND lose ≤2 units (only the two bait jeeps
|
| 177 |
+
# may be spent — burning armour fails) before the tight deadline.
|
| 178 |
description: >
|
| 179 |
+
Densest guard wall. Force stages from a seed-chosen latitude
|
| 180 |
+
(north or south). Land three tanks on the far east objective,
|
| 181 |
+
losing at most two units, within about 82 turns.
|
|
|
|
|
|
|
|
|
|
| 182 |
overrides:
|
| 183 |
actors:
|
| 184 |
# spawn_point 0 — northern staging (in-bounds, y=10/14)
|
|
@@ -41,13 +41,21 @@ levels:
|
|
| 41 |
# modest hold before the citadel counts. Generous clock. A beeline
|
| 42 |
# straight to C never satisfies the ordered latch → timeout LOSS.
|
| 43 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
description: >
|
| 45 |
-
|
| 46 |
-
then
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
after the hold. A greedy beeline to C, or idling, loses on the
|
| 50 |
-
clock.
|
| 51 |
overrides: {}
|
| 52 |
win_condition:
|
| 53 |
all_of:
|
|
|
|
| 41 |
# modest hold before the citadel counts. Generous clock. A beeline
|
| 42 |
# straight to C never satisfies the ordered latch → timeout LOSS.
|
| 43 |
easy:
|
| 44 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 45 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 46 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 47 |
+
#
|
| 48 |
+
# Strict ordered chain: first reach staging point A (mid-west),
|
| 49 |
+
# then transit point B (north-centre), then seize the citadel C
|
| 50 |
+
# (far east) — IN THAT ORDER. Reaching C without having passed A
|
| 51 |
+
# then B counts for nothing. The strike is timed: C only counts
|
| 52 |
+
# after the hold. A greedy beeline to C, or idling, loses on the
|
| 53 |
+
# clock.
|
| 54 |
description: >
|
| 55 |
+
Visit staging point A (mid-west), transit point B (north-centre),
|
| 56 |
+
then seize the citadel at C (far east) IN ORDER. C only counts
|
| 57 |
+
after turn 13 and before turn 26. Light pickets contest the
|
| 58 |
+
route.
|
|
|
|
|
|
|
| 59 |
overrides: {}
|
| 60 |
win_condition:
|
| 61 |
all_of:
|
|
@@ -161,17 +161,25 @@ levels:
|
|
| 161 |
# (count). max_turns 60 ⇒ reachable tick 93+90·59 = 5403;
|
| 162 |
# deadline 5400.
|
| 163 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
description: >
|
| 165 |
-
Four
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
EACH corner region: NE (82,9), NW (46,9), SE (82,31), SW (46,31).
|
| 170 |
-
Each band spawns at one corner — a pbox planted there shreds it.
|
| 171 |
-
Massing all four pillboxes on a single corner holds that corner
|
| 172 |
-
but lets the other three waves reach the fact. Stall, pure-army,
|
| 173 |
-
and concentrate all LOSE. The fact must survive; ≥9 enemy units
|
| 174 |
-
must die before tick 5400.
|
| 175 |
starting_cash: 2400
|
| 176 |
overrides:
|
| 177 |
actors:
|
|
@@ -225,17 +233,25 @@ levels:
|
|
| 225 |
# both fails three region clauses AND lets those heavier waves walk
|
| 226 |
# into the fact. max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 227 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
description: >
|
| 229 |
-
Four
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
the radius-4 disc of EACH corner region: NE (82,9), NW (46,9),
|
| 234 |
-
SE (82,31), SW (46,31). Massing all four pillboxes on a single
|
| 235 |
-
corner satisfies only one region clause and lets the three
|
| 236 |
-
uncovered waves walk into the fact. Stall, pure-army, and
|
| 237 |
-
concentrate all LOSE. The fact must survive; ≥13 enemy units
|
| 238 |
-
must die before tick 5400.
|
| 239 |
starting_cash: 2400
|
| 240 |
overrides:
|
| 241 |
actors:
|
|
@@ -292,20 +308,29 @@ levels:
|
|
| 292 |
# must READ the fact's longitude from observation. Kill bar 13.
|
| 293 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 294 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
description: >
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
(50,20) the corners are NE (68,9) NW (32,9) SE (68,31) SW
|
| 302 |
-
(32,31); for an EAST fact (78,20) they are NE (96,9) NW (60,9)
|
| 303 |
-
SE (96,31) SW (60,31) — read the fact's longitude from the
|
| 304 |
-
observation. Massing all four pillboxes on one corner, or
|
| 305 |
-
skirting the wrong (x=64) centre, satisfies at most one region
|
| 306 |
-
clause and lets the uncovered waves raze the fact. Stall,
|
| 307 |
-
pure-army, and concentrate all LOSE. The fact must survive;
|
| 308 |
-
≥13 enemy units must die before tick 5400.
|
| 309 |
starting_cash: 2400
|
| 310 |
overrides:
|
| 311 |
actors:
|
|
|
|
| 161 |
# (count). max_turns 60 ⇒ reachable tick 93+90·59 = 5403;
|
| 162 |
# deadline 5400.
|
| 163 |
easy:
|
| 164 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 165 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 166 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 167 |
+
#
|
| 168 |
+
# Four rusher bands of rifle infantry will charge your construction
|
| 169 |
+
# yard (fact, at map centre (64,20)) CONCURRENTLY from the four
|
| 170 |
+
# diagonal corners. Build 4 pillboxes (pbox — 600cr each, budget
|
| 171 |
+
# exactly 2400) AND place ONE of them inside the radius-4 disc of
|
| 172 |
+
# EACH corner region: NE (82,9), NW (46,9), SE (82,31), SW (46,31).
|
| 173 |
+
# Each band spawns at one corner — a pbox planted there shreds it.
|
| 174 |
+
# Massing all four pillboxes on a single corner holds that corner
|
| 175 |
+
# but lets the other three waves reach the fact. Stall, pure-army,
|
| 176 |
+
# and concentrate all LOSE. The fact must survive; ≥9 enemy units
|
| 177 |
+
# must die before tick 5400.
|
| 178 |
description: >
|
| 179 |
+
Four rifle bands will rush your central construction yard from all
|
| 180 |
+
four diagonal corners. Budget $2400 — build one pillbox in each
|
| 181 |
+
corner approach. Keep the yard alive, kill nine enemies, within
|
| 182 |
+
about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
starting_cash: 2400
|
| 184 |
overrides:
|
| 185 |
actors:
|
|
|
|
| 233 |
# both fails three region clauses AND lets those heavier waves walk
|
| 234 |
# into the fact. max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 235 |
medium:
|
| 236 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 237 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 238 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 239 |
+
#
|
| 240 |
+
# Four rusher bands — 4 rifle infantry each (16 total) — will
|
| 241 |
+
# charge your construction yard (fact, at map centre (64,20))
|
| 242 |
+
# CONCURRENTLY from the four diagonal corners. Build 4 pillboxes
|
| 243 |
+
# (budget exactly 2400cr = 4 pbox at 600 each) AND place ONE inside
|
| 244 |
+
# the radius-4 disc of EACH corner region: NE (82,9), NW (46,9),
|
| 245 |
+
# SE (82,31), SW (46,31). Massing all four pillboxes on a single
|
| 246 |
+
# corner satisfies only one region clause and lets the three
|
| 247 |
+
# uncovered waves walk into the fact. Stall, pure-army, and
|
| 248 |
+
# concentrate all LOSE. The fact must survive; ≥13 enemy units
|
| 249 |
+
# must die before tick 5400.
|
| 250 |
description: >
|
| 251 |
+
Four heavier rifle bands (sixteen total) will rush your central
|
| 252 |
+
construction yard from all four diagonal corners. Budget $2400 —
|
| 253 |
+
build one pillbox in each corner approach. Keep the yard alive,
|
| 254 |
+
kill thirteen enemies, within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
starting_cash: 2400
|
| 256 |
overrides:
|
| 257 |
actors:
|
|
|
|
| 308 |
# must READ the fact's longitude from observation. Kill bar 13.
|
| 309 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 310 |
hard:
|
| 311 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 312 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 313 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 314 |
+
#
|
| 315 |
+
# The agent construction yard (fact) flips between a WEST base
|
| 316 |
+
# (fact at (50,20)) and an EAST base (fact at (78,20)) by seed; the
|
| 317 |
+
# four corner regions of the skirt must follow. Build 4 pillboxes
|
| 318 |
+
# (budget 2400cr = 4 pbox at 600 each) AND place ONE inside the
|
| 319 |
+
# radius-4 disc of EACH corner of the CURRENT fact. For a WEST fact
|
| 320 |
+
# (50,20) the corners are NE (68,9) NW (32,9) SE (68,31) SW
|
| 321 |
+
# (32,31); for an EAST fact (78,20) they are NE (96,9) NW (60,9)
|
| 322 |
+
# SE (96,31) SW (60,31) — read the fact's longitude from the
|
| 323 |
+
# observation. Massing all four pillboxes on one corner, or
|
| 324 |
+
# skirting the wrong (x=64) centre, satisfies at most one region
|
| 325 |
+
# clause and lets the uncovered waves raze the fact. Stall,
|
| 326 |
+
# pure-army, and concentrate all LOSE. The fact must survive;
|
| 327 |
+
# ≥13 enemy units must die before tick 5400.
|
| 328 |
description: >
|
| 329 |
+
Same four-corner rush, but your construction yard is at the WEST
|
| 330 |
+
or EAST of the map depending on seed — the four corner approaches
|
| 331 |
+
shift with it. Budget $2400, build one pillbox in each corner of
|
| 332 |
+
the current yard. Keep it alive, kill thirteen, within about 60
|
| 333 |
+
turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
starting_cash: 2400
|
| 335 |
overrides:
|
| 336 |
actors:
|
|
@@ -133,17 +133,25 @@ levels:
|
|
| 133 |
# fails. Stall loses (clock OR fact razed); pure-army loses (count).
|
| 134 |
# max_turns 60 ⇒ reachable tick 93+90·59 = 5403; deadline 5400.
|
| 135 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
description: >
|
| 137 |
-
A
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
the rush at the doorstep of the protected asset. A thin pillbox
|
| 142 |
-
LINE strung along the attack lane (pboxes at x=20..35) fails the
|
| 143 |
-
region clause (none land inside the radius-4 disc around the
|
| 144 |
-
fact) and also lets the rifle band slip through. Stall, pure-
|
| 145 |
-
army, and pbox-line all LOSE. The fact must survive; ≥3 enemy
|
| 146 |
-
units must die before tick 5400.
|
| 147 |
starting_cash: 2400
|
| 148 |
overrides:
|
| 149 |
actors:
|
|
@@ -194,16 +202,24 @@ levels:
|
|
| 194 |
# 5 to require the cluster to actually fight, not just absorb.
|
| 195 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 196 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
description: >
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
fact. A pillbox LINE (1 at the fact, 3 along the lane) meets
|
| 203 |
-
the count but FAILS the region bar (1 of 4 inside the disc, not
|
| 204 |
-
the required 3) AND cannot mass enough firepower to blunt the
|
| 205 |
-
heavier band. Stall, pure-army, and pbox-line all LOSE. The
|
| 206 |
-
fact must survive; ≥5 enemy units must die before tick 5400.
|
| 207 |
starting_cash: 2400
|
| 208 |
overrides:
|
| 209 |
actors:
|
|
@@ -254,18 +270,26 @@ levels:
|
|
| 254 |
# grows to 4 (still 2400cr, exact). Kill bar 6.
|
| 255 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 256 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
description: >
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
CURRENT fact (either (10,14) or (10,26) — read it from the
|
| 263 |
-
observation). A line layout, a cluster around (10,20) (the
|
| 264 |
-
old centre that no longer holds the fact), or any plan that
|
| 265 |
-
doesn't follow the fact's latitude FAILS the region bar AND
|
| 266 |
-
lets the rush reach the fact. Stall, pure-army, pbox-line
|
| 267 |
-
all LOSE. The fact must survive; ≥6 enemy units must die
|
| 268 |
-
before tick 5400.
|
| 269 |
starting_cash: 2400
|
| 270 |
overrides:
|
| 271 |
actors:
|
|
|
|
| 133 |
# fails. Stall loses (clock OR fact razed); pure-army loses (count).
|
| 134 |
# max_turns 60 ⇒ reachable tick 93+90·59 = 5403; deadline 5400.
|
| 135 |
easy:
|
| 136 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 137 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 138 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 139 |
+
#
|
| 140 |
+
# A rusher band of rifle infantry charges your construction yard
|
| 141 |
+
# (fact, at (10,20)). Build 4 pillboxes (pbox — 600cr each, budget
|
| 142 |
+
# exactly 2400) AND place at least 3 of them INSIDE the radius-4
|
| 143 |
+
# disc around the fact, so their overlapping fields of fire shred
|
| 144 |
+
# the rush at the doorstep of the protected asset. A thin pillbox
|
| 145 |
+
# LINE strung along the attack lane (pboxes at x=20..35) fails the
|
| 146 |
+
# region clause (none land inside the radius-4 disc around the
|
| 147 |
+
# fact) and also lets the rifle band slip through. Stall, pure-
|
| 148 |
+
# army, and pbox-line all LOSE. The fact must survive; ≥3 enemy
|
| 149 |
+
# units must die before tick 5400.
|
| 150 |
description: >
|
| 151 |
+
A rifle band charges your construction yard from the east. Budget
|
| 152 |
+
$2400 — build four pillboxes with at least three sitting within
|
| 153 |
+
four cells of the yard. Keep the yard alive, kill three enemies,
|
| 154 |
+
within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
starting_cash: 2400
|
| 156 |
overrides:
|
| 157 |
actors:
|
|
|
|
| 202 |
# 5 to require the cluster to actually fight, not just absorb.
|
| 203 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 204 |
medium:
|
| 205 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 206 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 207 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 208 |
+
#
|
| 209 |
+
# The full rush band — 6 rifle infantry + 2 rocket soldiers —
|
| 210 |
+
# charges your construction yard (fact, at (10,20)). Build 4
|
| 211 |
+
# pillboxes (budget exactly 2400cr = 4 pbox at 600 each) AND
|
| 212 |
+
# place at least 3 of them INSIDE the radius-4 disc around the
|
| 213 |
+
# fact. A pillbox LINE (1 at the fact, 3 along the lane) meets
|
| 214 |
+
# the count but FAILS the region bar (1 of 4 inside the disc, not
|
| 215 |
+
# the required 3) AND cannot mass enough firepower to blunt the
|
| 216 |
+
# heavier band. Stall, pure-army, and pbox-line all LOSE. The
|
| 217 |
+
# fact must survive; ≥5 enemy units must die before tick 5400.
|
| 218 |
description: >
|
| 219 |
+
Heavier rush — 6 rifle infantry plus 2 rocket soldiers — charges
|
| 220 |
+
your construction yard. Budget $2400, build four pillboxes with
|
| 221 |
+
at least three within four cells of the yard. Keep the yard
|
| 222 |
+
alive, kill five enemies, within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
starting_cash: 2400
|
| 224 |
overrides:
|
| 225 |
actors:
|
|
|
|
| 270 |
# grows to 4 (still 2400cr, exact). Kill bar 6.
|
| 271 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 272 |
hard:
|
| 273 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 274 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 275 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 276 |
+
#
|
| 277 |
+
# The agent construction yard (fact) flips between NORTH (y=14)
|
| 278 |
+
# and SOUTH (y=26) by seed; the cluster centre must follow.
|
| 279 |
+
# Build 4 pillboxes (budget 2400cr = 4 pbox at 600 each) AND
|
| 280 |
+
# place at least 3 of them INSIDE the radius-4 disc around the
|
| 281 |
+
# CURRENT fact (either (10,14) or (10,26) — read it from the
|
| 282 |
+
# observation). A line layout, a cluster around (10,20) (the
|
| 283 |
+
# old centre that no longer holds the fact), or any plan that
|
| 284 |
+
# doesn't follow the fact's latitude FAILS the region bar AND
|
| 285 |
+
# lets the rush reach the fact. Stall, pure-army, pbox-line
|
| 286 |
+
# all LOSE. The fact must survive; ≥6 enemy units must die
|
| 287 |
+
# before tick 5400.
|
| 288 |
description: >
|
| 289 |
+
Same rush, but your construction yard is at the north or south of
|
| 290 |
+
the west edge depending on seed. Budget $2400, build four
|
| 291 |
+
pillboxes with at least three within four cells of the current
|
| 292 |
+
yard. Keep it alive, kill six, within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
starting_cash: 2400
|
| 294 |
overrides:
|
| 295 |
actors:
|
|
@@ -98,18 +98,26 @@ levels:
|
|
| 98 |
# clause AND the fact razed by the rush.
|
| 99 |
# max_turns 60 ⇒ reachable tick 93+90·59 = 5403; deadline 5400.
|
| 100 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
description: >
|
| 102 |
-
A
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
(60,19), (60,21), (60,22)) so the rusher cannot slip past on any
|
| 107 |
-
row. A cluster on the middle of the corridor satisfies the count
|
| 108 |
-
but FAILS every rung and lets the rush leak through; a random
|
| 109 |
-
scatter near the base fails every rung and kills nothing; a
|
| 110 |
-
pure-army layout (no pbox) fails the count and lets the rush
|
| 111 |
-
raze the fact. Your pillboxes must kill at least 4 of the rush;
|
| 112 |
-
your fact must survive.
|
| 113 |
starting_cash: 2400
|
| 114 |
overrides:
|
| 115 |
actors:
|
|
@@ -160,14 +168,21 @@ levels:
|
|
| 160 |
# heavier wave through to fail the kill bar AND raze the fact.
|
| 161 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 162 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
description: >
|
| 164 |
-
Same
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
(60,22)). The rush wave is heavier than easy — the complete LINE
|
| 168 |
-
must shred it at the corridor. Your pillboxes must kill at least
|
| 169 |
-
7 of the rush; a cluster, a scatter, and a pure-army layout all
|
| 170 |
-
lose; the fact must survive.
|
| 171 |
starting_cash: 2400
|
| 172 |
overrides:
|
| 173 |
actors:
|
|
@@ -217,15 +232,23 @@ levels:
|
|
| 217 |
# y=18..22 regardless of base latitude). max_turns 70 ⇒ reachable
|
| 218 |
# tick 93+90·69 = 6303; deadline 6300.
|
| 219 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
description: >
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
y=18..22 is a fixed map feature — covering the rows next to your
|
| 226 |
-
base instead (y=14..18 for NORTH, y=22..26 for SOUTH) FAILS the
|
| 227 |
-
rung clauses and lets the rush leak through. Your pillboxes must
|
| 228 |
-
kill at least 7 of the rush; the fact must survive.
|
| 229 |
starting_cash: 2400
|
| 230 |
overrides:
|
| 231 |
actors:
|
|
|
|
| 98 |
# clause AND the fact razed by the rush.
|
| 99 |
# max_turns 60 ⇒ reachable tick 93+90·59 = 5403; deadline 5400.
|
| 100 |
easy:
|
| 101 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 102 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 103 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 104 |
+
#
|
| 105 |
+
# A rusher band will spawn east of the corridor and must traverse
|
| 106 |
+
# the narrow corridor at x=60, y=18..22 to reach your base on the
|
| 107 |
+
# west. Build 4 pillboxes (pbox — 600cr each, budget exactly 2400)
|
| 108 |
+
# AND place ONE on each of the four corridor rungs (at (60,18),
|
| 109 |
+
# (60,19), (60,21), (60,22)) so the rusher cannot slip past on any
|
| 110 |
+
# row. A cluster on the middle of the corridor satisfies the count
|
| 111 |
+
# but FAILS every rung and lets the rush leak through; a random
|
| 112 |
+
# scatter near the base fails every rung and kills nothing; a
|
| 113 |
+
# pure-army layout (no pbox) fails the count and lets the rush
|
| 114 |
+
# raze the fact. Your pillboxes must kill at least 4 of the rush;
|
| 115 |
+
# your fact must survive.
|
| 116 |
description: >
|
| 117 |
+
A rush will funnel through the narrow mid-map corridor at x=60,
|
| 118 |
+
rows y=18 to 22. Budget $2400 — build a pillbox on each of those
|
| 119 |
+
four rows so nothing slips through. Kill four enemies and keep
|
| 120 |
+
your construction yard, within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
starting_cash: 2400
|
| 122 |
overrides:
|
| 123 |
actors:
|
|
|
|
| 168 |
# heavier wave through to fail the kill bar AND raze the fact.
|
| 169 |
# max_turns 60 ⇒ reachable tick 5403; deadline 5400.
|
| 170 |
medium:
|
| 171 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 172 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 173 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 174 |
+
#
|
| 175 |
+
# Same forced rusher corridor at x=60, y=18..22. Build 4 pillboxes
|
| 176 |
+
# (budget 2400cr = exactly 4 pbox at 600 each) AND place ONE on
|
| 177 |
+
# each of the four corridor rungs (at (60,18), (60,19), (60,21),
|
| 178 |
+
# (60,22)). The rush wave is heavier than easy — the complete LINE
|
| 179 |
+
# must shred it at the corridor. Your pillboxes must kill at least
|
| 180 |
+
# 7 of the rush; a cluster, a scatter, and a pure-army layout all
|
| 181 |
+
# lose; the fact must survive.
|
| 182 |
description: >
|
| 183 |
+
Same corridor at x=60, y=18 to 22, heavier rush wave. Budget
|
| 184 |
+
$2400 — build a pillbox on each of those four rows. Kill seven
|
| 185 |
+
enemies and keep your construction yard, within about 60 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
starting_cash: 2400
|
| 187 |
overrides:
|
| 188 |
actors:
|
|
|
|
| 232 |
# y=18..22 regardless of base latitude). max_turns 70 ⇒ reachable
|
| 233 |
# tick 93+90·69 = 6303; deadline 6300.
|
| 234 |
hard:
|
| 235 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 236 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 237 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 238 |
+
#
|
| 239 |
+
# Agent base latitude flips between NORTH (y=12) and SOUTH (y=28)
|
| 240 |
+
# by seed. Build 4 pillboxes (budget 2400cr = exactly 4 pbox at
|
| 241 |
+
# 600 each) AND place ONE on each of the four corridor rungs
|
| 242 |
+
# (at (60,18), (60,19), (60,21), (60,22)). The corridor at x=60
|
| 243 |
+
# y=18..22 is a fixed map feature — covering the rows next to your
|
| 244 |
+
# base instead (y=14..18 for NORTH, y=22..26 for SOUTH) FAILS the
|
| 245 |
+
# rung clauses and lets the rush leak through. Your pillboxes must
|
| 246 |
+
# kill at least 7 of the rush; the fact must survive.
|
| 247 |
description: >
|
| 248 |
+
Same corridor at x=60, y=18 to 22 — its location is a fixed map
|
| 249 |
+
feature even though your base latitude flips between north and
|
| 250 |
+
south by seed. Build a pillbox on each of those four rows. Kill
|
| 251 |
+
seven enemies and keep your yard, within about 70 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
starting_cash: 2400
|
| 253 |
overrides:
|
| 254 |
actors:
|
|
@@ -198,19 +198,27 @@ levels:
|
|
| 198 |
# follow-on path). Reserve 500 cr funds the powr rebuild with
|
| 199 |
# $200 slack. max_turns 30 → ceiling 2703 > 2700 ✓.
|
| 200 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
description: >
|
| 202 |
-
You inherit a
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
and a single enemy heavy tank ('4tnk') is staged adjacent to
|
| 207 |
-
it; the Power Plant will be DESTROYED in the opening turn.
|
| 208 |
-
To recover: queue another Power Plant ('build' "powr",
|
| 209 |
-
cost 300) and place it adjacent to the Construction Yard so
|
| 210 |
-
production stays online. Win = the Power Plant must be
|
| 211 |
-
DESTROYED and then REBUILT, AND you must still own a
|
| 212 |
-
Refinery, before tick 2700. Stalling, ignoring the rebuild,
|
| 213 |
-
or spending the reserve on army units all miss the bar.
|
| 214 |
starting_cash: 500
|
| 215 |
overrides:
|
| 216 |
actors:
|
|
@@ -270,20 +278,28 @@ levels:
|
|
| 270 |
# placement cell (e.g. adjacent to the fact on the OPPOSITE side
|
| 271 |
# from the strike lane). Reserve still 500 cr, deadline tightened.
|
| 272 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
description: >
|
| 274 |
-
Same base
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
fresh Power Plant that you place too close to the strike
|
| 279 |
-
lane. To recover: queue another Power Plant and place it
|
| 280 |
-
ADJACENT TO THE CONSTRUCTION YARD on the far side from the
|
| 281 |
-
strike lane (e.g. west of the fact). Win = the Power Plant
|
| 282 |
-
must be DESTROYED and then REBUILT, AND you must still own a
|
| 283 |
-
Refinery, before tick 2700. Stalling, ignoring the rebuild,
|
| 284 |
-
placing the new powr in the strike lane (where the lingering
|
| 285 |
-
4tnks will destroy it again), or spending the reserve on
|
| 286 |
-
army units all miss the bar.
|
| 287 |
starting_cash: 500
|
| 288 |
overrides:
|
| 289 |
actors:
|
|
@@ -331,18 +347,25 @@ levels:
|
|
| 331 |
# active agent assets. The active-latitude strikers do their
|
| 332 |
# one-shot powr kill identically to medium.
|
| 333 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
description: >
|
| 335 |
-
Same
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
SOUTH band (y≈22..30) of the map depending on the seed. Read
|
| 339 |
-
the Construction Yard's actual position from the observation
|
| 340 |
-
and place the replacement Power Plant adjacent to it on the
|
| 341 |
-
far side from the strike lane. A memorised "(10,18)" rebuild
|
| 342 |
-
cell will mis-place out of build radius on one of the two
|
| 343 |
-
spawns. Win = the Power Plant must be DESTROYED and then
|
| 344 |
-
REBUILT, AND you must still own a Refinery, before tick
|
| 345 |
-
2700. The same lazy / wrong-spend plays lose as on medium.
|
| 346 |
starting_cash: 500
|
| 347 |
overrides:
|
| 348 |
actors:
|
|
|
|
| 198 |
# follow-on path). Reserve 500 cr funds the powr rebuild with
|
| 199 |
# $200 slack. max_turns 30 → ceiling 2703 > 2700 ✓.
|
| 200 |
easy:
|
| 201 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 202 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 203 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 204 |
+
#
|
| 205 |
+
# You inherit a working production base — a Construction Yard
|
| 206 |
+
# ('fact'), an Ore Refinery ('proc'), a Power Plant ('powr'),
|
| 207 |
+
# a War Factory ('weap'), and one Ore Truck ('harv') with an
|
| 208 |
+
# ore patch — and $500 cash. The Power Plant is at LOW HEALTH
|
| 209 |
+
# and a single enemy heavy tank ('4tnk') is staged adjacent to
|
| 210 |
+
# it; the Power Plant will be DESTROYED in the opening turn.
|
| 211 |
+
# To recover: queue another Power Plant ('build' "powr",
|
| 212 |
+
# cost 300) and place it adjacent to the Construction Yard so
|
| 213 |
+
# production stays online. Win = the Power Plant must be
|
| 214 |
+
# DESTROYED and then REBUILT, AND you must still own a
|
| 215 |
+
# Refinery, before tick 2700. Stalling, ignoring the rebuild,
|
| 216 |
+
# or spending the reserve on army units all miss the bar.
|
| 217 |
description: >
|
| 218 |
+
You inherit a full base and $500 cash. Your low-HP Power Plant
|
| 219 |
+
will be destroyed on the opening turn by an adjacent enemy heavy
|
| 220 |
+
tank. Rebuild the Power Plant and keep your Refinery within about
|
| 221 |
+
30 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
starting_cash: 500
|
| 223 |
overrides:
|
| 224 |
actors:
|
|
|
|
| 278 |
# placement cell (e.g. adjacent to the fact on the OPPOSITE side
|
| 279 |
# from the strike lane). Reserve still 500 cr, deadline tightened.
|
| 280 |
medium:
|
| 281 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 282 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 283 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 284 |
+
#
|
| 285 |
+
# Same base as easy (fact, proc, low-HP powr, weap, harv, mine,
|
| 286 |
+
# one 3tnk defender, $500 reserve) but the enemy strike is now
|
| 287 |
+
# TWO heavy tanks adjacent to the Power Plant. The second tank
|
| 288 |
+
# guarantees the kill on the opening turn AND will engage a
|
| 289 |
+
# fresh Power Plant that you place too close to the strike
|
| 290 |
+
# lane. To recover: queue another Power Plant and place it
|
| 291 |
+
# ADJACENT TO THE CONSTRUCTION YARD on the far side from the
|
| 292 |
+
# strike lane (e.g. west of the fact). Win = the Power Plant
|
| 293 |
+
# must be DESTROYED and then REBUILT, AND you must still own a
|
| 294 |
+
# Refinery, before tick 2700. Stalling, ignoring the rebuild,
|
| 295 |
+
# placing the new powr in the strike lane (where the lingering
|
| 296 |
+
# 4tnks will destroy it again), or spending the reserve on
|
| 297 |
+
# army units all miss the bar.
|
| 298 |
description: >
|
| 299 |
+
Same base and $500 reserve, but TWO heavy tanks now sit beside
|
| 300 |
+
the low-HP Power Plant and will linger after the kill. Rebuild
|
| 301 |
+
the Power Plant somewhere it can survive, and keep your Refinery,
|
| 302 |
+
within about 30 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
starting_cash: 500
|
| 304 |
overrides:
|
| 305 |
actors:
|
|
|
|
| 347 |
# active agent assets. The active-latitude strikers do their
|
| 348 |
# one-shot powr kill identically to medium.
|
| 349 |
hard:
|
| 350 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 351 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 352 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 353 |
+
#
|
| 354 |
+
# Same exogenous-loss-and-rebuild task as medium (2× 4tnk
|
| 355 |
+
# strike, low-HP Power Plant, $500 reserve, tick 2700 deadline)
|
| 356 |
+
# but your base may begin in the NORTH band (y≈14..22) OR the
|
| 357 |
+
# SOUTH band (y≈22..30) of the map depending on the seed. Read
|
| 358 |
+
# the Construction Yard's actual position from the observation
|
| 359 |
+
# and place the replacement Power Plant adjacent to it on the
|
| 360 |
+
# far side from the strike lane. A memorised "(10,18)" rebuild
|
| 361 |
+
# cell will mis-place out of build radius on one of the two
|
| 362 |
+
# spawns. Win = the Power Plant must be DESTROYED and then
|
| 363 |
+
# REBUILT, AND you must still own a Refinery, before tick
|
| 364 |
+
# 2700. The same lazy / wrong-spend plays lose as on medium.
|
| 365 |
description: >
|
| 366 |
+
Same task as medium, but your base may sit in the NORTH or SOUTH
|
| 367 |
+
band depending on seed. Rebuild the Power Plant adjacent to your
|
| 368 |
+
Construction Yard, keep your Refinery, within about 30 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 369 |
starting_cash: 500
|
| 370 |
overrides:
|
| 371 |
actors:
|
|
@@ -122,16 +122,24 @@ levels:
|
|
| 122 |
# leave proc + the load-bearing structures standing. max_turns 40 →
|
| 123 |
# reachable tick 93 + 90·39 = 3603 > 3600 ✓.
|
| 124 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
description: >
|
| 126 |
-
Your base is
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
DOWN any combination of NON-ESSENTIAL drainers (tent + barr
|
| 131 |
-
sheds 40 exactly; weap alone sheds 30; dome alone sheds 40).
|
| 132 |
-
Do NOT sell anything — proc, tent, barr, weap, dome, fact must
|
| 133 |
-
remain standing. Do NOT power_down the lone powr — provided
|
| 134 |
-
power must stay ≥100. Deadline tick 3600.
|
| 135 |
starting_cash: 1000
|
| 136 |
overrides:
|
| 137 |
actors:
|
|
@@ -201,17 +209,25 @@ levels:
|
|
| 201 |
# selling, no shedding the powr). max_turns 36 → reachable tick
|
| 202 |
# 3243 > 3240 ✓.
|
| 203 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
description: >
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
NOT enough; weap + dome + tent = 90; dome + tent + barr +
|
| 210 |
-
hpad = 90; dome + fix = 70 NOT enough; dome + fix + tent =
|
| 211 |
-
90). No single power_down restores surplus — combinations
|
| 212 |
-
required. Do NOT sell anything — proc, tent, barr, weap,
|
| 213 |
-
dome, fix, hpad, fact must remain standing. Provided must
|
| 214 |
-
stay ≥100 (do not power_down the powr). Deadline tick 3240.
|
| 215 |
starting_cash: 1000
|
| 216 |
overrides:
|
| 217 |
actors:
|
|
@@ -280,13 +296,21 @@ levels:
|
|
| 280 |
# both spawn_point groups. The enemy marker has no spawn_point and
|
| 281 |
# always places.
|
| 282 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
description: >
|
| 284 |
-
Same
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
the observation. Do NOT sell anything; do NOT power_down the
|
| 289 |
-
powr. Deadline tick 3240.
|
| 290 |
starting_cash: 1000
|
| 291 |
overrides:
|
| 292 |
actors:
|
|
|
|
| 122 |
# leave proc + the load-bearing structures standing. max_turns 40 →
|
| 123 |
# reachable tick 93 + 90·39 = 3603 > 3600 ✓.
|
| 124 |
easy:
|
| 125 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 126 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 127 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 128 |
+
#
|
| 129 |
+
# Your base is OVERDRAWN: 1 Power Plant (powr, +100) carries five
|
| 130 |
+
# drainers — proc (−30), tent (−20), barr (−20), weap (−30),
|
| 131 |
+
# dome (−40) = drained 140, surplus −40 (production runs at 50%
|
| 132 |
+
# speed in low-power). Restore power_surplus_gte:0 by powering
|
| 133 |
+
# DOWN any combination of NON-ESSENTIAL drainers (tent + barr
|
| 134 |
+
# sheds 40 exactly; weap alone sheds 30; dome alone sheds 40).
|
| 135 |
+
# Do NOT sell anything — proc, tent, barr, weap, dome, fact must
|
| 136 |
+
# remain standing. Do NOT power_down the lone powr — provided
|
| 137 |
+
# power must stay ≥100. Deadline tick 3600.
|
| 138 |
description: >
|
| 139 |
+
Your base is overdrawn by 40 power. Use power_down to shed enough
|
| 140 |
+
non-essential load to restore non-negative surplus within about
|
| 141 |
+
40 turns. Do NOT sell any building; keep at least 100 provided
|
| 142 |
+
power (do not power down the Power Plant).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
starting_cash: 1000
|
| 144 |
overrides:
|
| 145 |
actors:
|
|
|
|
| 209 |
# selling, no shedding the powr). max_turns 36 → reachable tick
|
| 210 |
# 3243 > 3240 ✓.
|
| 211 |
medium:
|
| 212 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 213 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 214 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 215 |
+
#
|
| 216 |
+
# Same overdrawn base, but heavier load — drainers total 180
|
| 217 |
+
# (proc 30 + tent 20 + barr 20 + weap 30 + dome 40 + fix 30 +
|
| 218 |
+
# hpad 10 = 180). Surplus −80. You must shed ≥80 of load by
|
| 219 |
+
# powering DOWN non-essential drainers (e.g. weap + dome = 70 is
|
| 220 |
+
# NOT enough; weap + dome + tent = 90; dome + tent + barr +
|
| 221 |
+
# hpad = 90; dome + fix = 70 NOT enough; dome + fix + tent =
|
| 222 |
+
# 90). No single power_down restores surplus — combinations
|
| 223 |
+
# required. Do NOT sell anything — proc, tent, barr, weap,
|
| 224 |
+
# dome, fix, hpad, fact must remain standing. Provided must
|
| 225 |
+
# stay ≥100 (do not power_down the powr). Deadline tick 3240.
|
| 226 |
description: >
|
| 227 |
+
Heavier overdraw (surplus -80) on a larger base. Power down
|
| 228 |
+
enough non-essential buildings to restore non-negative surplus
|
| 229 |
+
within about 36 turns. No single shed will do it. Sell nothing;
|
| 230 |
+
keep at least 100 provided power.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
starting_cash: 1000
|
| 232 |
overrides:
|
| 233 |
actors:
|
|
|
|
| 296 |
# both spawn_point groups. The enemy marker has no spawn_point and
|
| 297 |
# always places.
|
| 298 |
hard:
|
| 299 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 300 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 301 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 302 |
+
#
|
| 303 |
+
# Same overdrawn base as medium (surplus −90, shed ≥90 of load by
|
| 304 |
+
# powering DOWN), but the base latitude FLIPS between NORTH (y=12)
|
| 305 |
+
# and SOUTH (y=28) by seed. The building IDs you must target with
|
| 306 |
+
# `power_down` are at the spawn-specific coords — read them from
|
| 307 |
+
# the observation. Do NOT sell anything; do NOT power_down the
|
| 308 |
+
# powr. Deadline tick 3240.
|
| 309 |
description: >
|
| 310 |
+
Same overdraw as medium, but base latitude flips between north
|
| 311 |
+
and south by seed. Read the buildings from the observation, power
|
| 312 |
+
down enough to restore non-negative surplus within about 36
|
| 313 |
+
turns. Sell nothing; keep at least 100 provided power.
|
|
|
|
|
|
|
| 314 |
starting_cash: 1000
|
| 315 |
overrides:
|
| 316 |
actors:
|
|
@@ -128,15 +128,22 @@ levels:
|
|
| 128 |
# the chain; the model cannot also blow the budget on a single 400-
|
| 129 |
# cost mis-build (tent) and still complete the chain.
|
| 130 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
description: >
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
a 'proc' IN THAT ORDER (the powr must appear FIRST), before
|
| 136 |
-
tick 3600. The Refinery REQUIRES a Power Plant — queuing
|
| 137 |
-
'proc' first is silently rejected by the engine. Stalling,
|
| 138 |
-
building infantry/army, or attempting the Refinery before the
|
| 139 |
-
Power Plant all miss the clock and LOSE.
|
| 140 |
starting_cash: 1900
|
| 141 |
overrides:
|
| 142 |
actors:
|
|
@@ -165,14 +172,20 @@ levels:
|
|
| 165 |
# powr that the model rebuilds twice does drain) tightens the
|
| 166 |
# margin. max_turns 32 → reachable tick 93 + 90·31 = 2883 > 2880 ✓.
|
| 167 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
description: >
|
| 169 |
-
Same opening
|
| 170 |
-
|
| 171 |
-
budget ($1750 — covers the chain with $50 to spare) and
|
| 172 |
-
tighter clock (tick 2880). The Refinery REQUIRES the Power
|
| 173 |
-
Plant — queuing 'proc' first is silently rejected. Stalling,
|
| 174 |
-
army-building, or attempting 'proc' before 'powr' all run out
|
| 175 |
-
the clock and LOSE.
|
| 176 |
starting_cash: 1750
|
| 177 |
overrides:
|
| 178 |
actors:
|
|
@@ -203,16 +216,23 @@ levels:
|
|
| 203 |
# read from the actual fact position. max_turns 32 → reachable
|
| 204 |
# tick 2883 > 2880 ✓.
|
| 205 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
description: >
|
| 207 |
-
Same
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
depending on the seed. Read the fact's actual position from
|
| 211 |
-
the observation and place 'powr' and 'proc' adjacent to it.
|
| 212 |
-
A memorised "(20,20)" opening will mis-place the buildings
|
| 213 |
-
out-of-radius on one of the two spawns. The Refinery still
|
| 214 |
-
REQUIRES the Power Plant; out-of-order builds are silently
|
| 215 |
-
rejected and the clock runs out as a LOSS.
|
| 216 |
starting_cash: 1750
|
| 217 |
overrides:
|
| 218 |
actors:
|
|
|
|
| 128 |
# the chain; the model cannot also blow the budget on a single 400-
|
| 129 |
# cost mis-build (tent) and still complete the chain.
|
| 130 |
easy:
|
| 131 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 132 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 133 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 134 |
+
#
|
| 135 |
+
# You start with a Construction Yard ('fact') at (20,20) and
|
| 136 |
+
# $1900. Build a Power Plant ('powr', cost 300) FIRST, then an
|
| 137 |
+
# Ore Refinery ('proc', cost 1400). Win = own a 'powr' AND own
|
| 138 |
+
# a 'proc' IN THAT ORDER (the powr must appear FIRST), before
|
| 139 |
+
# tick 3600. The Refinery REQUIRES a Power Plant — queuing
|
| 140 |
+
# 'proc' first is silently rejected by the engine. Stalling,
|
| 141 |
+
# building infantry/army, or attempting the Refinery before the
|
| 142 |
+
# Power Plant all miss the clock and LOSE.
|
| 143 |
description: >
|
| 144 |
+
Start with a Construction Yard and $1900. Build a Power Plant,
|
| 145 |
+
then an Ore Refinery, within about 40 turns. The Refinery
|
| 146 |
+
requires a Power Plant first.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
starting_cash: 1900
|
| 148 |
overrides:
|
| 149 |
actors:
|
|
|
|
| 172 |
# powr that the model rebuilds twice does drain) tightens the
|
| 173 |
# margin. max_turns 32 → reachable tick 93 + 90·31 = 2883 > 2880 ✓.
|
| 174 |
medium:
|
| 175 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 176 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 177 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 178 |
+
#
|
| 179 |
+
# Same opening: 'fact' at (20,20), no power, no economy. Build
|
| 180 |
+
# 'powr' FIRST (cost 300), THEN 'proc' (cost 1400). Tighter
|
| 181 |
+
# budget ($1750 — covers the chain with $50 to spare) and
|
| 182 |
+
# tighter clock (tick 2880). The Refinery REQUIRES the Power
|
| 183 |
+
# Plant — queuing 'proc' first is silently rejected. Stalling,
|
| 184 |
+
# army-building, or attempting 'proc' before 'powr' all run out
|
| 185 |
+
# the clock and LOSE.
|
| 186 |
description: >
|
| 187 |
+
Same opening with tighter cash ($1750) and a tighter clock
|
| 188 |
+
(about 32 turns). Build a Power Plant, then an Ore Refinery.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
starting_cash: 1750
|
| 190 |
overrides:
|
| 191 |
actors:
|
|
|
|
| 216 |
# read from the actual fact position. max_turns 32 → reachable
|
| 217 |
# tick 2883 > 2880 ✓.
|
| 218 |
hard:
|
| 219 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 220 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 221 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 222 |
+
#
|
| 223 |
+
# Same opening as medium (powr FIRST then proc, tight $1750
|
| 224 |
+
# budget, tick 2880 clock) but your Construction Yard may begin
|
| 225 |
+
# in the NORTH band (y≈12) or the SOUTH band (y≈28) of the map
|
| 226 |
+
# depending on the seed. Read the fact's actual position from
|
| 227 |
+
# the observation and place 'powr' and 'proc' adjacent to it.
|
| 228 |
+
# A memorised "(20,20)" opening will mis-place the buildings
|
| 229 |
+
# out-of-radius on one of the two spawns. The Refinery still
|
| 230 |
+
# REQUIRES the Power Plant; out-of-order builds are silently
|
| 231 |
+
# rejected and the clock runs out as a LOSS.
|
| 232 |
description: >
|
| 233 |
+
Same task as medium ($1750, about 32 turns), but your Construction
|
| 234 |
+
Yard sits in the north or south band depending on seed. Read its
|
| 235 |
+
position from the observation and place buildings adjacent to it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
starting_cash: 1750
|
| 237 |
overrides:
|
| 238 |
actors:
|
|
@@ -147,18 +147,25 @@ levels:
|
|
| 147 |
# 6th well inside the window. max_turns 35 → reachable tick
|
| 148 |
# 93 + 90·34 = 3153 > 2701 ✓ (the deadline bites as a real LOSS).
|
| 149 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
description: >
|
| 151 |
-
|
| 152 |
-
(
|
| 153 |
-
|
| 154 |
-
$850 each) before tick 2700. ONE war factory cannot build 6
|
| 155 |
-
tanks in time — it is a single serial production line. You have
|
| 156 |
-
cash for a SECOND war factory ($2000); two factories produce
|
| 157 |
-
vehicles IN PARALLEL and roughly double your output. Build the
|
| 158 |
-
second weap, place it, and keep BOTH queues full. Win = own ≥6
|
| 159 |
-
medium tanks AND your fact still stands, before tick 2700.
|
| 160 |
-
Stalling or spamming tanks from the single factory both miss
|
| 161 |
-
the quota and LOSE on the clock.
|
| 162 |
starting_cash: 9000
|
| 163 |
overrides:
|
| 164 |
actors:
|
|
@@ -188,14 +195,20 @@ levels:
|
|
| 188 |
# by then, comfortable WIN). Same quota, same base. max_turns 33 →
|
| 189 |
# reachable tick 93 + 90·32 = 2973 > 2614 ✓.
|
| 190 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
description: >
|
| 192 |
-
Same base as easy
|
| 193 |
-
|
| 194 |
-
tick 2613. A single war factory clears only ~5 tanks by then.
|
| 195 |
-
Build a SECOND war factory and feed both queues — two factories
|
| 196 |
-
produce vehicles in parallel and double your throughput. Win =
|
| 197 |
-
own ≥6 medium tanks AND your fact still stands, before tick
|
| 198 |
-
2613. Stall or single-factory spam both LOSE on the clock.
|
| 199 |
starting_cash: 9000
|
| 200 |
overrides:
|
| 201 |
actors:
|
|
@@ -228,17 +241,24 @@ levels:
|
|
| 228 |
# the spawn latitude varies. max_turns 33 → reachable tick 2973
|
| 229 |
# > 2614 ✓.
|
| 230 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
description: >
|
| 232 |
-
Same
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
NORTH band (y≈14) or the SOUTH band (y≈26) depending on the
|
| 236 |
-
seed. Read your War Factory's actual position from the
|
| 237 |
-
observation and place the second weap adjacent to it. A single
|
| 238 |
-
factory clears only ~5 tanks by the deadline; build the second
|
| 239 |
-
and feed both queues. Win = own ≥6 medium tanks AND your fact
|
| 240 |
-
still stands, before tick 2613. Stall or single-factory spam
|
| 241 |
-
both LOSE on the clock.
|
| 242 |
starting_cash: 9000
|
| 243 |
overrides:
|
| 244 |
actors:
|
|
|
|
| 147 |
# 6th well inside the window. max_turns 35 → reachable tick
|
| 148 |
# 93 + 90·34 = 3153 > 2701 ✓ (the deadline bites as a real LOSS).
|
| 149 |
easy:
|
| 150 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 151 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 152 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 153 |
+
#
|
| 154 |
+
# You have a full base — Construction Yard (fact), Refinery
|
| 155 |
+
# (proc), Power Plant (powr), Service Depot (fix) and ONE War
|
| 156 |
+
# Factory (weap) — and $9000. Field 6 medium tanks (2tnk, cost
|
| 157 |
+
# $850 each) before tick 2700. ONE war factory cannot build 6
|
| 158 |
+
# tanks in time — it is a single serial production line. You have
|
| 159 |
+
# cash for a SECOND war factory ($2000); two factories produce
|
| 160 |
+
# vehicles IN PARALLEL and roughly double your output. Build the
|
| 161 |
+
# second weap, place it, and keep BOTH queues full. Win = own ≥6
|
| 162 |
+
# medium tanks AND your fact still stands, before tick 2700.
|
| 163 |
+
# Stalling or spamming tanks from the single factory both miss
|
| 164 |
+
# the quota and LOSE on the clock.
|
| 165 |
description: >
|
| 166 |
+
Full base with one War Factory and $9000. Field six medium tanks
|
| 167 |
+
(2tnk) within about 30 turns, keeping your construction yard. One
|
| 168 |
+
factory cannot meet the deadline.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
starting_cash: 9000
|
| 170 |
overrides:
|
| 171 |
actors:
|
|
|
|
| 195 |
# by then, comfortable WIN). Same quota, same base. max_turns 33 →
|
| 196 |
# reachable tick 93 + 90·32 = 2973 > 2614 ✓.
|
| 197 |
medium:
|
| 198 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 199 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 200 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 201 |
+
#
|
| 202 |
+
# Same base as easy (fact + proc + powr + fix + ONE weap, $9000)
|
| 203 |
+
# but a tighter deadline: field 6 medium tanks (2tnk) before
|
| 204 |
+
# tick 2613. A single war factory clears only ~5 tanks by then.
|
| 205 |
+
# Build a SECOND war factory and feed both queues — two factories
|
| 206 |
+
# produce vehicles in parallel and double your throughput. Win =
|
| 207 |
+
# own ≥6 medium tanks AND your fact still stands, before tick
|
| 208 |
+
# 2613. Stall or single-factory spam both LOSE on the clock.
|
| 209 |
description: >
|
| 210 |
+
Same base as easy with a tighter deadline. Field six medium tanks
|
| 211 |
+
within about 29 turns, keeping your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
starting_cash: 9000
|
| 213 |
overrides:
|
| 214 |
actors:
|
|
|
|
| 241 |
# the spawn latitude varies. max_turns 33 → reachable tick 2973
|
| 242 |
# > 2614 ✓.
|
| 243 |
hard:
|
| 244 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 245 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 246 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 247 |
+
#
|
| 248 |
+
# Same throughput call as medium (field 6 medium tanks before
|
| 249 |
+
# tick 2613 from a base with ONE pre-placed war factory; build a
|
| 250 |
+
# SECOND for parallel output) but your base may begin in the
|
| 251 |
+
# NORTH band (y≈14) or the SOUTH band (y≈26) depending on the
|
| 252 |
+
# seed. Read your War Factory's actual position from the
|
| 253 |
+
# observation and place the second weap adjacent to it. A single
|
| 254 |
+
# factory clears only ~5 tanks by the deadline; build the second
|
| 255 |
+
# and feed both queues. Win = own ≥6 medium tanks AND your fact
|
| 256 |
+
# still stands, before tick 2613. Stall or single-factory spam
|
| 257 |
+
# both LOSE on the clock.
|
| 258 |
description: >
|
| 259 |
+
Same task as medium, but your base may sit in the north or south
|
| 260 |
+
band depending on seed. Field six medium tanks within about 29
|
| 261 |
+
turns, keeping your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
starting_cash: 9000
|
| 263 |
overrides:
|
| 264 |
actors:
|
|
@@ -135,23 +135,31 @@ levels:
|
|
| 135 |
# (23,21)..(26,25), never enter region, never engage barr → LOSS
|
| 136 |
# on the deadline.
|
| 137 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
description: >
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
staging area (62,20) ≈38 cells east of your tent. Win = at
|
| 144 |
-
least 3 of your units inside a radius-5 disc around (62,20)
|
| 145 |
-
AND ≥1 enemy unit/building killed AND before tick 2700. The
|
| 146 |
-
tent's default rally point is right next to the tent —
|
| 147 |
-
freshly-built infantry pile at (23–26, 21–25) and never
|
| 148 |
-
engage. You must call set_rally_point on the tent with
|
| 149 |
-
target (62,20) BEFORE (or right after) you queue the first
|
| 150 |
-
Rifle Infantry ('e1', cost 100), so every subsequent unit
|
| 151 |
-
walks to the forward zone and chews the enemy barr down.
|
| 152 |
-
Stalling, building without setting the rally forward, or
|
| 153 |
-
setting the rally to a near-base cell all miss the deadline
|
| 154 |
-
and LOSE.
|
| 155 |
starting_cash: 1500
|
| 156 |
overrides:
|
| 157 |
actors:
|
|
@@ -185,17 +193,24 @@ levels:
|
|
| 185 |
# but a model that stalls for even a few turns before setting the
|
| 186 |
# rally misses the window. Stall / no-rally still LOSE outright.
|
| 187 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
description: >
|
| 189 |
-
Same opening —
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
disc around (62,20) AND ≥1 kill AND before tick 1900 (tight
|
| 193 |
-
— a few stall turns before the rally call will miss the
|
| 194 |
-
window). Tent default rally piles units at the base; you
|
| 195 |
-
must call set_rally_point on the tent with target (62,20)
|
| 196 |
-
and queue infantry ('e1', cost 100) IMMEDIATELY. Stall,
|
| 197 |
-
no-rally, or rally-to-a-near-base-cell all LOSE on the
|
| 198 |
-
deadline.
|
| 199 |
starting_cash: 1500
|
| 200 |
overrides:
|
| 201 |
actors:
|
|
@@ -228,20 +243,28 @@ levels:
|
|
| 228 |
# the centreline (62,20)). Same tight clock as medium. max_turns
|
| 229 |
# 22 → reachable tick 1983 > 1900 ✓.
|
| 230 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
description: >
|
| 232 |
-
Same
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
band (y≈28) of the map depending on the seed. Read the
|
| 237 |
-
tent's actual position from the observation and call
|
| 238 |
-
set_rally_point on the tent with target (62,20) — the
|
| 239 |
-
centreline forward zone is fixed regardless of which spawn
|
| 240 |
-
you got. A memorised "set rally from y=22" opening will
|
| 241 |
-
still target (62,20), but your tent id and starting cells
|
| 242 |
-
will differ per seed. The Barracks default rally piles
|
| 243 |
-
units at the base; without an explicit forward rally call
|
| 244 |
-
the units never reach (62,20) and the SLA is missed.
|
| 245 |
starting_cash: 1500
|
| 246 |
overrides:
|
| 247 |
actors:
|
|
|
|
| 135 |
# (23,21)..(26,25), never enter region, never engage barr → LOSS
|
| 136 |
# on the deadline.
|
| 137 |
easy:
|
| 138 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 139 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 140 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 141 |
+
#
|
| 142 |
+
# Production logistics opening. You start with a Construction
|
| 143 |
+
# Yard ('fact') at (20,20), a Power Plant ('powr') at (22,22),
|
| 144 |
+
# and a Barracks ('tent') at (24,22) — total cash $1500. An
|
| 145 |
+
# enemy Barracks ('barr', the kill target) sits at the FORWARD
|
| 146 |
+
# staging area (62,20) ≈38 cells east of your tent. Win = at
|
| 147 |
+
# least 3 of your units inside a radius-5 disc around (62,20)
|
| 148 |
+
# AND ≥1 enemy unit/building killed AND before tick 2700. The
|
| 149 |
+
# tent's default rally point is right next to the tent —
|
| 150 |
+
# freshly-built infantry pile at (23–26, 21–25) and never
|
| 151 |
+
# engage. You must call set_rally_point on the tent with
|
| 152 |
+
# target (62,20) BEFORE (or right after) you queue the first
|
| 153 |
+
# Rifle Infantry ('e1', cost 100), so every subsequent unit
|
| 154 |
+
# walks to the forward zone and chews the enemy barr down.
|
| 155 |
+
# Stalling, building without setting the rally forward, or
|
| 156 |
+
# setting the rally to a near-base cell all miss the deadline
|
| 157 |
+
# and LOSE.
|
| 158 |
description: >
|
| 159 |
+
You have a Construction Yard, Power Plant, and Barracks with
|
| 160 |
+
$1500. An enemy barracks sits at the forward zone (62,20). Get
|
| 161 |
+
at least three of your units into a radius-5 disc around (62,20)
|
| 162 |
+
and kill one enemy, within about 30 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
starting_cash: 1500
|
| 164 |
overrides:
|
| 165 |
actors:
|
|
|
|
| 193 |
# but a model that stalls for even a few turns before setting the
|
| 194 |
# rally misses the window. Stall / no-rally still LOSE outright.
|
| 195 |
medium:
|
| 196 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 197 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 198 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 199 |
+
#
|
| 200 |
+
# Same opening — fact (20,20), powr (22,22), tent (24,22),
|
| 201 |
+
# $1500 — but the SLA tightens. Enemy 'barr' kill target at
|
| 202 |
+
# (62,20); win requires ≥3 of your units inside a radius-5
|
| 203 |
+
# disc around (62,20) AND ≥1 kill AND before tick 1900 (tight
|
| 204 |
+
# — a few stall turns before the rally call will miss the
|
| 205 |
+
# window). Tent default rally piles units at the base; you
|
| 206 |
+
# must call set_rally_point on the tent with target (62,20)
|
| 207 |
+
# and queue infantry ('e1', cost 100) IMMEDIATELY. Stall,
|
| 208 |
+
# no-rally, or rally-to-a-near-base-cell all LOSE on the
|
| 209 |
+
# deadline.
|
| 210 |
description: >
|
| 211 |
+
Same opening with a tighter clock — about 21 turns. Get at least
|
| 212 |
+
three units into a radius-5 disc around the forward zone (62,20)
|
| 213 |
+
and kill one enemy.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
starting_cash: 1500
|
| 215 |
overrides:
|
| 216 |
actors:
|
|
|
|
| 243 |
# the centreline (62,20)). Same tight clock as medium. max_turns
|
| 244 |
# 22 → reachable tick 1983 > 1900 ✓.
|
| 245 |
hard:
|
| 246 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 247 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 248 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 249 |
+
#
|
| 250 |
+
# Same SLA-tight opening as medium (forward zone (62,20),
|
| 251 |
+
# enemy 'barr' there, ≥3 units in r=5 disc + ≥1 kill before
|
| 252 |
+
# tick 1900) but your Construction Yard, Power Plant, and
|
| 253 |
+
# Barracks may begin in the NORTH band (y≈16) or the SOUTH
|
| 254 |
+
# band (y≈28) of the map depending on the seed. Read the
|
| 255 |
+
# tent's actual position from the observation and call
|
| 256 |
+
# set_rally_point on the tent with target (62,20) — the
|
| 257 |
+
# centreline forward zone is fixed regardless of which spawn
|
| 258 |
+
# you got. A memorised "set rally from y=22" opening will
|
| 259 |
+
# still target (62,20), but your tent id and starting cells
|
| 260 |
+
# will differ per seed. The Barracks default rally piles
|
| 261 |
+
# units at the base; without an explicit forward rally call
|
| 262 |
+
# the units never reach (62,20) and the SLA is missed.
|
| 263 |
description: >
|
| 264 |
+
Same task as medium, but your base sits in the north or south
|
| 265 |
+
band depending on seed. The forward zone (62,20) is the same
|
| 266 |
+
either way. Get three units there and kill one enemy within
|
| 267 |
+
about 21 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
starting_cash: 1500
|
| 269 |
overrides:
|
| 270 |
actors:
|
|
@@ -181,20 +181,28 @@ levels:
|
|
| 181 |
# 2400]; max_turns 28 → reachable tick 93 + 90·27 = 2523, so the
|
| 182 |
# after_ticks 2401 fail bites.
|
| 183 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
description: >
|
| 185 |
-
Three of your
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
grenadiers barely scratch it; it survives on its own. The
|
| 190 |
-
refinery is on a lethal trajectory: it dies within a few turns
|
| 191 |
-
unless you toggle REPAIR on it now. Repairing the refinery also
|
| 192 |
-
keeps its attackers pinned, so the war factory stays safe. Win
|
| 193 |
-
when the refinery and the war factory are both still standing
|
| 194 |
-
after tick 1200 and before tick 2400. If the refinery falls, or
|
| 195 |
-
the clock runs out with the win unmet, you lose. Stalling and
|
| 196 |
-
repairing the most-damaged-looking building (the pillbox) both
|
| 197 |
-
lose the refinery.
|
| 198 |
overrides:
|
| 199 |
actors:
|
| 200 |
# proc — HIGH value, LETHAL trajectory. 3 grenadiers kill the
|
|
@@ -241,18 +249,26 @@ levels:
|
|
| 241 |
# max_turns 31 → reachable tick 93 + 90·30 = 2793, so after_ticks
|
| 242 |
# 2701 bites.
|
| 243 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
description: >
|
| 245 |
-
|
| 246 |
-
war factory
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
refinery AND the war factory are both on lethal trajectories:
|
| 250 |
-
each dies within a few turns unless you toggle REPAIR on it. Win
|
| 251 |
-
when the refinery and the war factory are both still standing
|
| 252 |
-
after tick 1700 and before tick 2700. If either falls, or the
|
| 253 |
-
clock runs out with the win unmet, you lose. Stalling, repairing
|
| 254 |
-
only the pillbox, and repairing only one of the two critical
|
| 255 |
-
buildings all lose.
|
| 256 |
overrides:
|
| 257 |
actors:
|
| 258 |
- {type: proc, owner: agent, position: [20, 8]}
|
|
@@ -292,19 +308,26 @@ levels:
|
|
| 292 |
# agent unit (the base is otherwise building-only). Same composition
|
| 293 |
# and clock as medium (proc + weap both lethal; pbox decoy).
|
| 294 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
description: >
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
memorised opening cannot generalise. The pillbox is pre-damaged
|
| 300 |
-
to ~30% HP and looks the most damaged but is low value, heavily
|
| 301 |
-
armoured, and survives on its own; the refinery and the war
|
| 302 |
-
factory are both on lethal trajectories and each needs REPAIR.
|
| 303 |
-
Win when the refinery and the war factory are both still standing
|
| 304 |
-
after tick 1700 and before tick 2700. If either falls, or the
|
| 305 |
-
clock runs out with the win unmet, you lose. Stalling, repairing
|
| 306 |
-
only the pillbox, and repairing only one critical building all
|
| 307 |
-
lose.
|
| 308 |
overrides:
|
| 309 |
actors:
|
| 310 |
# WEST base group (spawn_point 0). Full base + bands duplicated
|
|
|
|
| 181 |
# 2400]; max_turns 28 → reachable tick 93 + 90·27 = 2523, so the
|
| 182 |
# after_ticks 2401 fail bites.
|
| 183 |
easy:
|
| 184 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 185 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 186 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 187 |
+
#
|
| 188 |
+
# Three of your structures are under attrition: the refinery
|
| 189 |
+
# (proc), the war factory (weap), and the pillbox (pbox). The
|
| 190 |
+
# pillbox is already damaged to about 30% HP and looks the most
|
| 191 |
+
# damaged — but it is low value, heavily armoured, and the
|
| 192 |
+
# grenadiers barely scratch it; it survives on its own. The
|
| 193 |
+
# refinery is on a lethal trajectory: it dies within a few turns
|
| 194 |
+
# unless you toggle REPAIR on it now. Repairing the refinery also
|
| 195 |
+
# keeps its attackers pinned, so the war factory stays safe. Win
|
| 196 |
+
# when the refinery and the war factory are both still standing
|
| 197 |
+
# after tick 1200 and before tick 2400. If the refinery falls, or
|
| 198 |
+
# the clock runs out with the win unmet, you lose. Stalling and
|
| 199 |
+
# repairing the most-damaged-looking building (the pillbox) both
|
| 200 |
+
# lose the refinery.
|
| 201 |
description: >
|
| 202 |
+
Three of your buildings — refinery, war factory, and pillbox —
|
| 203 |
+
are taking fire. The pillbox starts at 30% HP. Use repair to
|
| 204 |
+
keep the refinery and war factory both alive from turn 14 to
|
| 205 |
+
about turn 27.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
overrides:
|
| 207 |
actors:
|
| 208 |
# proc — HIGH value, LETHAL trajectory. 3 grenadiers kill the
|
|
|
|
| 249 |
# max_turns 31 → reachable tick 93 + 90·30 = 2793, so after_ticks
|
| 250 |
# 2701 bites.
|
| 251 |
medium:
|
| 252 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 253 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 254 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 255 |
+
#
|
| 256 |
+
# Three structures are under attrition: the refinery (proc), the
|
| 257 |
+
# war factory (weap), and the pillbox (pbox). The pillbox is
|
| 258 |
+
# already damaged to about 30% HP and looks the most damaged — but
|
| 259 |
+
# it is low value, heavily armoured, and survives on its own. The
|
| 260 |
+
# refinery AND the war factory are both on lethal trajectories:
|
| 261 |
+
# each dies within a few turns unless you toggle REPAIR on it. Win
|
| 262 |
+
# when the refinery and the war factory are both still standing
|
| 263 |
+
# after tick 1700 and before tick 2700. If either falls, or the
|
| 264 |
+
# clock runs out with the win unmet, you lose. Stalling, repairing
|
| 265 |
+
# only the pillbox, and repairing only one of the two critical
|
| 266 |
+
# buildings all lose.
|
| 267 |
description: >
|
| 268 |
+
Same three buildings under fire, but now both the refinery and
|
| 269 |
+
war factory are on lethal trajectories. The pillbox is the
|
| 270 |
+
pre-damaged decoy. Keep the refinery and war factory alive from
|
| 271 |
+
turn 19 to about turn 30.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
overrides:
|
| 273 |
actors:
|
| 274 |
- {type: proc, owner: agent, position: [20, 8]}
|
|
|
|
| 308 |
# agent unit (the base is otherwise building-only). Same composition
|
| 309 |
# and clock as medium (proc + weap both lethal; pbox decoy).
|
| 310 |
hard:
|
| 311 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 312 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 313 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 314 |
+
#
|
| 315 |
+
# Three structures — the refinery (proc), the war factory (weap),
|
| 316 |
+
# and the pillbox (pbox) — are under attrition from three grenadier
|
| 317 |
+
# bands. Your base stages from a seed-chosen longitude, so a single
|
| 318 |
+
# memorised opening cannot generalise. The pillbox is pre-damaged
|
| 319 |
+
# to ~30% HP and looks the most damaged but is low value, heavily
|
| 320 |
+
# armoured, and survives on its own; the refinery and the war
|
| 321 |
+
# factory are both on lethal trajectories and each needs REPAIR.
|
| 322 |
+
# Win when the refinery and the war factory are both still standing
|
| 323 |
+
# after tick 1700 and before tick 2700. If either falls, or the
|
| 324 |
+
# clock runs out with the win unmet, you lose. Stalling, repairing
|
| 325 |
+
# only the pillbox, and repairing only one critical building all
|
| 326 |
+
# lose.
|
| 327 |
description: >
|
| 328 |
+
Same task as medium, but your base sits at a seed-chosen
|
| 329 |
+
longitude. Keep the refinery and war factory alive from turn 19
|
| 330 |
+
to about turn 30.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 331 |
overrides:
|
| 332 |
actors:
|
| 333 |
# WEST base group (spawn_point 0). Full base + bands duplicated
|
|
@@ -163,20 +163,28 @@ levels:
|
|
| 163 |
# paired with after_ticks 4501 in fail ⇒ a non-finisher is a real
|
| 164 |
# reachable timeout LOSS (not a draw).
|
| 165 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 166 |
description: >
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
will raze the refinery within ~25-30 turns. Your starting
|
| 172 |
-
cash is 800 — not enough to build a new refinery (cost
|
| 173 |
-
1400). SELL the exposed refinery (refunds 700) and use the
|
| 174 |
-
recouped cash + starting cash to BUILD a new refinery at
|
| 175 |
-
the safe target region around (16, 8) — north of the rush
|
| 176 |
-
lane. Win by having a refinery at the safe region AND the
|
| 177 |
-
Construction Yard still alive AND before tick 4500. Stall,
|
| 178 |
-
build-without-selling (cash gated), or placing the new
|
| 179 |
-
refinery anywhere outside the safe region all lose.
|
| 180 |
starting_cash: 800
|
| 181 |
overrides:
|
| 182 |
actors:
|
|
@@ -231,19 +239,26 @@ levels:
|
|
| 231 |
# of ~25-30. Same tick budget so the win window is tighter against
|
| 232 |
# the same after_ticks 5401 fail.
|
| 233 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
description: >
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
and will raze the refinery faster (~20 turns). Your
|
| 239 |
-
starting cash is 700 — exactly the sell refund of a
|
| 240 |
-
refinery, half the build cost. You MUST sell the exposed
|
| 241 |
-
refinery to free the second half of the cash, then build a
|
| 242 |
-
new refinery at the safe target region around (16, 8). Win
|
| 243 |
-
by having a refinery at the safe region AND the Construction
|
| 244 |
-
Yard still alive AND before tick 4500. Stalling, building
|
| 245 |
-
without selling (cash blocks the build), or placing the new
|
| 246 |
-
refinery in the central lane all lose.
|
| 247 |
starting_cash: 700
|
| 248 |
overrides:
|
| 249 |
actors:
|
|
@@ -276,20 +291,28 @@ levels:
|
|
| 276 |
# (16, 8)" cell loses on the SOUTH spawn (the safe region there
|
| 277 |
# is (16, 36) not (16, 8)).
|
| 278 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
description: >
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
at the centre lane. Hunt bands are incoming on the centre
|
| 285 |
-
lane and will raze the refinery within ~20 turns. Your
|
| 286 |
-
starting cash is 700 — exactly half the refinery build
|
| 287 |
-
cost. You MUST sell the exposed refinery and use the
|
| 288 |
-
recouped cash to build a new refinery at the safe target
|
| 289 |
-
region of your OWN latitude (around (16, 8) for the NORTH
|
| 290 |
-
spawn, (16, 36) for the SOUTH spawn). Win by having a
|
| 291 |
-
refinery at the safe region of your latitude AND the
|
| 292 |
-
Construction Yard still alive AND before tick 4500.
|
| 293 |
starting_cash: 700
|
| 294 |
overrides:
|
| 295 |
actors:
|
|
|
|
| 163 |
# paired with after_ticks 4501 in fail ⇒ a non-finisher is a real
|
| 164 |
# reachable timeout LOSS (not a draw).
|
| 165 |
easy:
|
| 166 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 167 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 168 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 169 |
+
#
|
| 170 |
+
# You own a Construction Yard (fact) and a Power Plant (powr)
|
| 171 |
+
# at the safe far north-west corner and a forward Refinery
|
| 172 |
+
# (proc) at the centre lane. A small hunt band (2 rifle
|
| 173 |
+
# infantry) is incoming from the east on the centre lane and
|
| 174 |
+
# will raze the refinery within ~25-30 turns. Your starting
|
| 175 |
+
# cash is 800 — not enough to build a new refinery (cost
|
| 176 |
+
# 1400). SELL the exposed refinery (refunds 700) and use the
|
| 177 |
+
# recouped cash + starting cash to BUILD a new refinery at
|
| 178 |
+
# the safe target region around (16, 8) — north of the rush
|
| 179 |
+
# lane. Win by having a refinery at the safe region AND the
|
| 180 |
+
# Construction Yard still alive AND before tick 4500. Stall,
|
| 181 |
+
# build-without-selling (cash gated), or placing the new
|
| 182 |
+
# refinery anywhere outside the safe region all lose.
|
| 183 |
description: >
|
| 184 |
+
Your forward refinery is on the centre lane in the path of an
|
| 185 |
+
incoming rifle band; $800 alone cannot fund a new refinery. End
|
| 186 |
+
up with a refinery near (16,8) in the safe north-west corner and
|
| 187 |
+
keep your construction yard, within about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
starting_cash: 800
|
| 189 |
overrides:
|
| 190 |
actors:
|
|
|
|
| 239 |
# of ~25-30. Same tick budget so the win window is tighter against
|
| 240 |
# the same after_ticks 5401 fail.
|
| 241 |
medium:
|
| 242 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 243 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 244 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 245 |
+
#
|
| 246 |
+
# You own a Construction Yard and a Power Plant at the safe
|
| 247 |
+
# far north-west corner and a forward Refinery at the centre
|
| 248 |
+
# lane. A heavier hunt band (3 rifle infantry) is incoming
|
| 249 |
+
# and will raze the refinery faster (~20 turns). Your
|
| 250 |
+
# starting cash is 700 — exactly the sell refund of a
|
| 251 |
+
# refinery, half the build cost. You MUST sell the exposed
|
| 252 |
+
# refinery to free the second half of the cash, then build a
|
| 253 |
+
# new refinery at the safe target region around (16, 8). Win
|
| 254 |
+
# by having a refinery at the safe region AND the Construction
|
| 255 |
+
# Yard still alive AND before tick 4500. Stalling, building
|
| 256 |
+
# without selling (cash blocks the build), or placing the new
|
| 257 |
+
# refinery in the central lane all lose.
|
| 258 |
description: >
|
| 259 |
+
Heavier rifle band on the centre lane and only $700 cash. End up
|
| 260 |
+
with a refinery near (16,8) in the safe north-west corner and
|
| 261 |
+
keep your construction yard, within about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
starting_cash: 700
|
| 263 |
overrides:
|
| 264 |
actors:
|
|
|
|
| 291 |
# (16, 8)" cell loses on the SOUTH spawn (the safe region there
|
| 292 |
# is (16, 36) not (16, 8)).
|
| 293 |
hard:
|
| 294 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 295 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 296 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 297 |
+
#
|
| 298 |
+
# Your base stages from a seed-chosen latitude (NORTH y=4 or
|
| 299 |
+
# SOUTH y=36) — a single memorised target cell cannot
|
| 300 |
+
# generalise. You own a Construction Yard and a Power Plant
|
| 301 |
+
# at the safe corner of your latitude and a forward Refinery
|
| 302 |
+
# at the centre lane. Hunt bands are incoming on the centre
|
| 303 |
+
# lane and will raze the refinery within ~20 turns. Your
|
| 304 |
+
# starting cash is 700 — exactly half the refinery build
|
| 305 |
+
# cost. You MUST sell the exposed refinery and use the
|
| 306 |
+
# recouped cash to build a new refinery at the safe target
|
| 307 |
+
# region of your OWN latitude (around (16, 8) for the NORTH
|
| 308 |
+
# spawn, (16, 36) for the SOUTH spawn). Win by having a
|
| 309 |
+
# refinery at the safe region of your latitude AND the
|
| 310 |
+
# Construction Yard still alive AND before tick 4500.
|
| 311 |
description: >
|
| 312 |
+
Same task as medium, but your base sits in the north or south
|
| 313 |
+
corner depending on seed. End up with a refinery on your own
|
| 314 |
+
latitude's safe shoulder and keep your construction yard, within
|
| 315 |
+
about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
starting_cash: 700
|
| 317 |
overrides:
|
| 318 |
actors:
|
|
@@ -125,17 +125,25 @@ levels:
|
|
| 125 |
# the `then:` chain never completes ⇒ after_ticks LOSS. Stall never
|
| 126 |
# builds anything ⇒ LOSS on the same clause.
|
| 127 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
description: >
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
chain costs exactly $3700 (powr $300 + proc $1400 + weap $2000).
|
| 134 |
-
Any extra structure bought before weap (a barracks/tent $500, a
|
| 135 |
-
pillbox $600, an infantry unit) exhausts the budget and weap can
|
| 136 |
-
never be funded — you LOSE on the clock. The `then:` chain
|
| 137 |
-
enforces the exact order; placing weap before proc cannot satisfy
|
| 138 |
-
it (and the engine refuses too: weap's prerequisite is proc).
|
| 139 |
starting_cash: 3750
|
| 140 |
overrides:
|
| 141 |
actors:
|
|
@@ -169,15 +177,21 @@ levels:
|
|
| 169 |
# chain still fits; ANY wasteful spend overruns even harder. Same
|
| 170 |
# generous clock T = 3200 — money, not time, remains the teeth.
|
| 171 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
description: >
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
($3720) barely covers the minimal path ($3700: powr $300 +
|
| 176 |
-
proc $1400 + weap $2000). There is no ore and no income. Any
|
| 177 |
-
extra structure (tent / pbox / an infantry unit) bought before
|
| 178 |
-
weap exhausts the budget and weap can never be funded. The
|
| 179 |
-
`then:` chain enforces the exact order; weap before proc cannot
|
| 180 |
-
satisfy it.
|
| 181 |
starting_cash: 3720
|
| 182 |
overrides:
|
| 183 |
actors:
|
|
@@ -208,15 +222,22 @@ levels:
|
|
| 208 |
# do NOT honour spawn_point (CLAUDE.md), so the lone enemy `fact`
|
| 209 |
# landmark always places.
|
| 210 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
description: >
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
minimal path ($3700). There is no ore and no income. Any extra
|
| 216 |
-
structure (tent / pbox / an infantry unit) bought before weap
|
| 217 |
-
exhausts the budget and weap can never be funded. Placement
|
| 218 |
-
that memorises one spawn's geometry cannot generalise; compute
|
| 219 |
-
placement relative to your actual fact each run.
|
| 220 |
starting_cash: 3720
|
| 221 |
overrides:
|
| 222 |
actors:
|
|
|
|
| 125 |
# the `then:` chain never completes ⇒ after_ticks LOSS. Stall never
|
| 126 |
# builds anything ⇒ LOSS on the same clause.
|
| 127 |
easy:
|
| 128 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 129 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 130 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 131 |
+
#
|
| 132 |
+
# Build a war factory (weap) by spending the LEAST cash, on the
|
| 133 |
+
# ONLY affordable prerequisite chain: powr → proc → weap. Your
|
| 134 |
+
# starting cash ($3750) is a fixed budget — there is no ore and no
|
| 135 |
+
# income, so it is all the money you will ever have. The minimal
|
| 136 |
+
# chain costs exactly $3700 (powr $300 + proc $1400 + weap $2000).
|
| 137 |
+
# Any extra structure bought before weap (a barracks/tent $500, a
|
| 138 |
+
# pillbox $600, an infantry unit) exhausts the budget and weap can
|
| 139 |
+
# never be funded — you LOSE on the clock. The `then:` chain
|
| 140 |
+
# enforces the exact order; placing weap before proc cannot satisfy
|
| 141 |
+
# it (and the engine refuses too: weap's prerequisite is proc).
|
| 142 |
description: >
|
| 143 |
+
Cash $3750 is a fixed budget — no ore, no income. End up owning a
|
| 144 |
+
Power Plant, then an Ore Refinery, then a War Factory, in that
|
| 145 |
+
order, within about 36 turns. Any other building drains the
|
| 146 |
+
budget below what the war factory needs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
starting_cash: 3750
|
| 148 |
overrides:
|
| 149 |
actors:
|
|
|
|
| 177 |
# chain still fits; ANY wasteful spend overruns even harder. Same
|
| 178 |
# generous clock T = 3200 — money, not time, remains the teeth.
|
| 179 |
medium:
|
| 180 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 181 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 182 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 183 |
+
#
|
| 184 |
+
# Build a war factory (weap) on the cost-minimal prerequisite
|
| 185 |
+
# chain: powr → proc → weap. Tighter budget — your starting cash
|
| 186 |
+
# ($3720) barely covers the minimal path ($3700: powr $300 +
|
| 187 |
+
# proc $1400 + weap $2000). There is no ore and no income. Any
|
| 188 |
+
# extra structure (tent / pbox / an infantry unit) bought before
|
| 189 |
+
# weap exhausts the budget and weap can never be funded. The
|
| 190 |
+
# `then:` chain enforces the exact order; weap before proc cannot
|
| 191 |
+
# satisfy it.
|
| 192 |
description: >
|
| 193 |
+
Same task with a tighter $3720 budget. Build Power Plant, then
|
| 194 |
+
Refinery, then War Factory, in order, within about 36 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
starting_cash: 3720
|
| 196 |
overrides:
|
| 197 |
actors:
|
|
|
|
| 222 |
# do NOT honour spawn_point (CLAUDE.md), so the lone enemy `fact`
|
| 223 |
# landmark always places.
|
| 224 |
hard:
|
| 225 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 226 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 227 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 228 |
+
#
|
| 229 |
+
# Build a war factory (weap) on the cost-minimal prerequisite
|
| 230 |
+
# chain: powr → proc → weap, from a seed-chosen base (NORTH or
|
| 231 |
+
# SOUTH). Tight budget — starting cash ($3720) barely covers the
|
| 232 |
+
# minimal path ($3700). There is no ore and no income. Any extra
|
| 233 |
+
# structure (tent / pbox / an infantry unit) bought before weap
|
| 234 |
+
# exhausts the budget and weap can never be funded. Placement
|
| 235 |
+
# that memorises one spawn's geometry cannot generalise; compute
|
| 236 |
+
# placement relative to your actual fact each run.
|
| 237 |
description: >
|
| 238 |
+
Same task as medium, but your base sits in the north or south
|
| 239 |
+
band depending on seed. Build the powr→proc→weap chain in order
|
| 240 |
+
within about 36 turns on $3720.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
starting_cash: 3720
|
| 242 |
overrides:
|
| 243 |
actors:
|
|
@@ -98,15 +98,22 @@ levels:
|
|
| 98 |
# turns) finishes at ~tick 3063, beyond T ⇒ LOSS. Stall finishes
|
| 99 |
# never ⇒ LOSS on the after_ticks fail clause.
|
| 100 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
description: >
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
infantry training queue) wastes the budget and you LOSE on the
|
| 106 |
-
clock. The `then:` chain enforces the exact order — placing
|
| 107 |
-
weap before proc cannot satisfy it (and the engine refuses too:
|
| 108 |
-
weap's prerequisite is proc). Optimal play finishes by tick
|
| 109 |
-
~2613; the deadline is 3000.
|
| 110 |
starting_cash: 5000
|
| 111 |
overrides:
|
| 112 |
actors:
|
|
@@ -146,12 +153,18 @@ levels:
|
|
| 146 |
# No additional pieces — the SAME cost-optimal chain, executed
|
| 147 |
# with less slack.
|
| 148 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
description: >
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
detour (tent / second powr / infantry queue) makes you miss.
|
| 153 |
-
The `then:` chain enforces the exact order; weap before proc
|
| 154 |
-
cannot satisfy it. Optimal play finishes by tick ~2613.
|
| 155 |
starting_cash: 5000
|
| 156 |
overrides:
|
| 157 |
actors:
|
|
@@ -184,13 +197,20 @@ levels:
|
|
| 184 |
# actors do NOT honour spawn_point (CLAUDE.md), so the lone
|
| 185 |
# enemy `fact` always places.
|
| 186 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
description: >
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
powr / infantry queue) lose on the clock. Placement that
|
| 192 |
-
memorises one spawn's geometry cannot generalise; compute
|
| 193 |
-
placement relative to your actual fact each run.
|
| 194 |
starting_cash: 5000
|
| 195 |
overrides:
|
| 196 |
actors:
|
|
|
|
| 98 |
# turns) finishes at ~tick 3063, beyond T ⇒ LOSS. Stall finishes
|
| 99 |
# never ⇒ LOSS on the after_ticks fail clause.
|
| 100 |
easy:
|
| 101 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 102 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 103 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 104 |
+
#
|
| 105 |
+
# Build a war factory (weap) as fast as possible by following the
|
| 106 |
+
# ONLY cost-optimal prerequisite chain: powr → proc → weap. Any
|
| 107 |
+
# detour (a barracks/tent, a redundant power plant, an early
|
| 108 |
+
# infantry training queue) wastes the budget and you LOSE on the
|
| 109 |
+
# clock. The `then:` chain enforces the exact order — placing
|
| 110 |
+
# weap before proc cannot satisfy it (and the engine refuses too:
|
| 111 |
+
# weap's prerequisite is proc). Optimal play finishes by tick
|
| 112 |
+
# ~2613; the deadline is 3000.
|
| 113 |
description: >
|
| 114 |
+
$5000 cash plus ore. End up owning a Power Plant, then an Ore
|
| 115 |
+
Refinery, then a War Factory, in that order, within about 34
|
| 116 |
+
turns. Detours through other buildings overrun the clock.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
starting_cash: 5000
|
| 118 |
overrides:
|
| 119 |
actors:
|
|
|
|
| 153 |
# No additional pieces — the SAME cost-optimal chain, executed
|
| 154 |
# with less slack.
|
| 155 |
medium:
|
| 156 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 157 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 158 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 159 |
+
#
|
| 160 |
+
# Build a war factory (weap) on the cost-optimal prerequisite
|
| 161 |
+
# chain: powr → proc → weap. Tighter deadline (2800 ticks) — any
|
| 162 |
+
# detour (tent / second powr / infantry queue) makes you miss.
|
| 163 |
+
# The `then:` chain enforces the exact order; weap before proc
|
| 164 |
+
# cannot satisfy it. Optimal play finishes by tick ~2613.
|
| 165 |
description: >
|
| 166 |
+
Same task with a tighter clock (about 31 turns). Build Power
|
| 167 |
+
Plant, then Refinery, then War Factory, in order.
|
|
|
|
|
|
|
|
|
|
| 168 |
starting_cash: 5000
|
| 169 |
overrides:
|
| 170 |
actors:
|
|
|
|
| 197 |
# actors do NOT honour spawn_point (CLAUDE.md), so the lone
|
| 198 |
# enemy `fact` always places.
|
| 199 |
hard:
|
| 200 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 201 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 202 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 203 |
+
#
|
| 204 |
+
# Build a war factory (weap) on the cost-optimal prerequisite
|
| 205 |
+
# chain: powr → proc → weap, from a seed-chosen base (NORTH or
|
| 206 |
+
# SOUTH). Tight 2800-tick deadline — detours (tent / extra
|
| 207 |
+
# powr / infantry queue) lose on the clock. Placement that
|
| 208 |
+
# memorises one spawn's geometry cannot generalise; compute
|
| 209 |
+
# placement relative to your actual fact each run.
|
| 210 |
description: >
|
| 211 |
+
Same task as medium, but your base sits in the north or south
|
| 212 |
+
band depending on seed. Build powr→proc→weap in order within
|
| 213 |
+
about 31 turns.
|
|
|
|
|
|
|
|
|
|
| 214 |
starting_cash: 5000
|
| 215 |
overrides:
|
| 216 |
actors:
|
|
@@ -172,24 +172,32 @@ levels:
|
|
| 172 |
# tanks. Generous clock (within_ticks 5400, max_turns 60 → ceiling
|
| 173 |
# 5403 ✓). The strike fires at tick 1500.
|
| 174 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
description: >
|
| 176 |
-
You inherit a
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
EXPOSED: an enemy strike will RAZE it at tick 1500. It is your
|
| 181 |
-
only power. If it is your only power when the strike lands,
|
| 182 |
-
your grid goes negative, your war factory drops to half
|
| 183 |
-
production speed, and your tank army cannot finish in time. To
|
| 184 |
-
stay resilient: build a SECOND Power Plant ('build' "powr",
|
| 185 |
-
cost 300) and place it next to your Construction Yard in the
|
| 186 |
-
safe west base BEFORE tick 1500, build a War Factory ('build'
|
| 187 |
-
"weap", cost 2000), then produce three medium tanks ('build'
|
| 188 |
-
"2tnk", cost 850 each). WIN = you brought power then a war
|
| 189 |
-
factory online, you still own a Power Plant, you have 3 medium
|
| 190 |
-
tanks, and you still own your Construction Yard, before tick
|
| 191 |
-
5400. Stalling, or relying on the single exposed power plant
|
| 192 |
-
with no redundant backup, misses the bar.
|
| 193 |
starting_cash: 6000
|
| 194 |
overrides:
|
| 195 |
actors:
|
|
@@ -252,23 +260,30 @@ levels:
|
|
| 252 |
# before committing the redundant powr now risks the deadline. The
|
| 253 |
# single-point-of-failure failure modes lose exactly as on easy.
|
| 254 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
description: >
|
| 256 |
-
Same
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
strike will RAZE at tick 1500. Build a SECOND Power Plant
|
| 260 |
-
('build' "powr", 300) in the safe west base next to your
|
| 261 |
-
Construction Yard BEFORE tick 1500, build a War Factory
|
| 262 |
-
('build' "weap", 2000), then produce three medium tanks
|
| 263 |
-
('build' "2tnk", 850 each).
|
| 264 |
-
The deadline is tighter — tick 4500 — so commit the redundant
|
| 265 |
-
power plant early; do not wait for the exposed one to fall. If
|
| 266 |
-
the strike leaves you with no power, the war factory halves its
|
| 267 |
-
output and the army misses the clock. WIN = you brought power
|
| 268 |
-
then a war factory online, you still own a Power Plant, you
|
| 269 |
-
have 3 medium tanks, and you still own your Construction Yard,
|
| 270 |
-
before tick 4500. Stalling, or relying on the single exposed
|
| 271 |
-
power plant, misses the bar.
|
| 272 |
starting_cash: 6000
|
| 273 |
overrides:
|
| 274 |
actors:
|
|
@@ -316,21 +331,29 @@ levels:
|
|
| 316 |
# generalise — the agent must read the actual Construction Yard
|
| 317 |
# latitude and place the redundant power plant beside it.
|
| 318 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
description: >
|
| 320 |
-
Same
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
depending on the seed. Read the Construction Yard's actual
|
| 325 |
-
position from the observation and place the redundant Power
|
| 326 |
-
Plant beside it in the safe west base BEFORE tick 1500; build a
|
| 327 |
-
War Factory; then produce three medium tanks. A memorised
|
| 328 |
-
placement cell will mis-place out of build radius on one of the
|
| 329 |
-
two spawns. WIN = you brought power then a war factory online,
|
| 330 |
-
you still own a Power Plant, you have 3 medium tanks, and you
|
| 331 |
-
still own your Construction Yard, before tick 4500. The same
|
| 332 |
-
single-point-of-failure plays — stalling, or relying on the
|
| 333 |
-
lone exposed power plant — lose as on medium.
|
| 334 |
starting_cash: 6000
|
| 335 |
overrides:
|
| 336 |
actors:
|
|
|
|
| 172 |
# tanks. Generous clock (within_ticks 5400, max_turns 60 → ceiling
|
| 173 |
# 5403 ✓). The strike fires at tick 1500.
|
| 174 |
easy:
|
| 175 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 176 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 177 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 178 |
+
#
|
| 179 |
+
# You inherit a partial base — a Construction Yard ('fact'), an
|
| 180 |
+
# Ore Refinery ('proc'), a Service Depot ('fix'), an Ore Truck
|
| 181 |
+
# ('harv') with an ore patch, and ONE Power Plant ('powr'). That
|
| 182 |
+
# power plant sits FORWARD at the east edge of your base and is
|
| 183 |
+
# EXPOSED: an enemy strike will RAZE it at tick 1500. It is your
|
| 184 |
+
# only power. If it is your only power when the strike lands,
|
| 185 |
+
# your grid goes negative, your war factory drops to half
|
| 186 |
+
# production speed, and your tank army cannot finish in time. To
|
| 187 |
+
# stay resilient: build a SECOND Power Plant ('build' "powr",
|
| 188 |
+
# cost 300) and place it next to your Construction Yard in the
|
| 189 |
+
# safe west base BEFORE tick 1500, build a War Factory ('build'
|
| 190 |
+
# "weap", cost 2000), then produce three medium tanks ('build'
|
| 191 |
+
# "2tnk", cost 850 each). WIN = you brought power then a war
|
| 192 |
+
# factory online, you still own a Power Plant, you have 3 medium
|
| 193 |
+
# tanks, and you still own your Construction Yard, before tick
|
| 194 |
+
# 5400. Stalling, or relying on the single exposed power plant
|
| 195 |
+
# with no redundant backup, misses the bar.
|
| 196 |
description: >
|
| 197 |
+
You inherit a base with $6000 and one forward Power Plant that an
|
| 198 |
+
enemy strike razes at turn 17. End up owning a Power Plant, a
|
| 199 |
+
War Factory, and three medium tanks (2tnk) within about 60 turns,
|
| 200 |
+
keeping your Construction Yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
starting_cash: 6000
|
| 202 |
overrides:
|
| 203 |
actors:
|
|
|
|
| 260 |
# before committing the redundant powr now risks the deadline. The
|
| 261 |
# single-point-of-failure failure modes lose exactly as on easy.
|
| 262 |
medium:
|
| 263 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 264 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 265 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 266 |
+
#
|
| 267 |
+
# Same inherited base as easy — a Construction Yard, an Ore
|
| 268 |
+
# Refinery, a Service Depot, an Ore Truck with an ore patch, and
|
| 269 |
+
# ONE EXPOSED Power Plant forward at the east edge that an enemy
|
| 270 |
+
# strike will RAZE at tick 1500. Build a SECOND Power Plant
|
| 271 |
+
# ('build' "powr", 300) in the safe west base next to your
|
| 272 |
+
# Construction Yard BEFORE tick 1500, build a War Factory
|
| 273 |
+
# ('build' "weap", 2000), then produce three medium tanks
|
| 274 |
+
# ('build' "2tnk", 850 each).
|
| 275 |
+
# The deadline is tighter — tick 4500 — so commit the redundant
|
| 276 |
+
# power plant early; do not wait for the exposed one to fall. If
|
| 277 |
+
# the strike leaves you with no power, the war factory halves its
|
| 278 |
+
# output and the army misses the clock. WIN = you brought power
|
| 279 |
+
# then a war factory online, you still own a Power Plant, you
|
| 280 |
+
# have 3 medium tanks, and you still own your Construction Yard,
|
| 281 |
+
# before tick 4500. Stalling, or relying on the single exposed
|
| 282 |
+
# power plant, misses the bar.
|
| 283 |
description: >
|
| 284 |
+
Same base and strike as easy, but a tighter clock — about 50
|
| 285 |
+
turns. End up owning a Power Plant, a War Factory, and three
|
| 286 |
+
medium tanks, keeping your Construction Yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
starting_cash: 6000
|
| 288 |
overrides:
|
| 289 |
actors:
|
|
|
|
| 331 |
# generalise — the agent must read the actual Construction Yard
|
| 332 |
# latitude and place the redundant power plant beside it.
|
| 333 |
hard:
|
| 334 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 335 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 336 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 337 |
+
#
|
| 338 |
+
# Same N+1 build-order task as medium (one EXPOSED Power Plant
|
| 339 |
+
# forward at the east edge that an enemy strike razes at tick
|
| 340 |
+
# 1500, $6000, tick 4500 deadline) but your base may begin in
|
| 341 |
+
# the NORTH band (y≈12) OR the SOUTH band (y≈26) of the map
|
| 342 |
+
# depending on the seed. Read the Construction Yard's actual
|
| 343 |
+
# position from the observation and place the redundant Power
|
| 344 |
+
# Plant beside it in the safe west base BEFORE tick 1500; build a
|
| 345 |
+
# War Factory; then produce three medium tanks. A memorised
|
| 346 |
+
# placement cell will mis-place out of build radius on one of the
|
| 347 |
+
# two spawns. WIN = you brought power then a war factory online,
|
| 348 |
+
# you still own a Power Plant, you have 3 medium tanks, and you
|
| 349 |
+
# still own your Construction Yard, before tick 4500. The same
|
| 350 |
+
# single-point-of-failure plays — stalling, or relying on the
|
| 351 |
+
# lone exposed power plant — lose as on medium.
|
| 352 |
description: >
|
| 353 |
+
Same task as medium, but your base sits in the north or south
|
| 354 |
+
band depending on seed. End up owning a Power Plant, a War
|
| 355 |
+
Factory, and three medium tanks within about 50 turns, keeping
|
| 356 |
+
your Construction Yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
starting_cash: 6000
|
| 358 |
overrides:
|
| 359 |
actors:
|
|
@@ -155,17 +155,24 @@ levels:
|
|
| 155 |
# as a real reachable LOSS (the old max_turns 25 could hit the turn
|
| 156 |
# cap at tick ~1578 before the deadline → degenerate draw).
|
| 157 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
description: >
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
garrison of 5 rifle infantry is advancing from the east. The
|
| 163 |
-
objective needs only basic units: train an e1 swarm and rally it
|
| 164 |
-
at your base front to meet the garrison. Do NOT climb the tech
|
| 165 |
-
chain to a war factory and tanks — that is a whole tech tier the
|
| 166 |
-
objective never asked for and it overruns the clock. Win when
|
| 167 |
-
≥4 enemy units are killed AND your fact still stands, before
|
| 168 |
-
tick 1600. Stalling or teching to tanks both LOSE on the clock.
|
| 169 |
starting_cash: 6000
|
| 170 |
overrides:
|
| 171 |
actors:
|
|
@@ -199,15 +206,22 @@ levels:
|
|
| 199 |
# max_turns 30 keeps the loop alive to that terminal frame so the
|
| 200 |
# after_ticks 1401 fail bites as a real reachable LOSS.
|
| 201 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
description: >
|
| 203 |
-
Same base
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
e1 swarm and rally it at your base front. Climbing the tech
|
| 207 |
-
chain to a war factory and tanks is an unnecessary tier that
|
| 208 |
-
overruns the clock. Win when ≥6 enemy units are killed AND your
|
| 209 |
-
fact still stands, before tick 1400. Stalling or teching to
|
| 210 |
-
tanks both LOSE on the clock.
|
| 211 |
starting_cash: 6000
|
| 212 |
overrides:
|
| 213 |
actors:
|
|
@@ -243,15 +257,22 @@ levels:
|
|
| 243 |
# real reachable LOSS (the old max_turns 23 hit the turn cap at
|
| 244 |
# tick ~1578 before the deadline on seeds 1/3 → degenerate draw).
|
| 245 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
description: >
|
| 247 |
-
Same
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
(y≈14) or the SOUTH band (y≈26) depending on the seed. Read
|
| 251 |
-
your barracks' actual position from the observation, train the
|
| 252 |
-
e1 swarm and rally it at your base front. Win when ≥6 enemy
|
| 253 |
-
units are killed AND your fact still stands, before tick 1400.
|
| 254 |
-
Stalling or teching to tanks both LOSE on the clock.
|
| 255 |
starting_cash: 6000
|
| 256 |
overrides:
|
| 257 |
actors:
|
|
|
|
| 155 |
# as a real reachable LOSS (the old max_turns 25 could hit the turn
|
| 156 |
# cap at tick ~1578 before the deadline → degenerate draw).
|
| 157 |
easy:
|
| 158 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 159 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 160 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 161 |
+
#
|
| 162 |
+
# Your base already has a Construction Yard (fact) and an Allied
|
| 163 |
+
# barracks (tent) — so rifle infantry (e1, $100 each) are
|
| 164 |
+
# buildable from turn 1 with NO prior tech step. A light enemy
|
| 165 |
+
# garrison of 5 rifle infantry is advancing from the east. The
|
| 166 |
+
# objective needs only basic units: train an e1 swarm and rally it
|
| 167 |
+
# at your base front to meet the garrison. Do NOT climb the tech
|
| 168 |
+
# chain to a war factory and tanks — that is a whole tech tier the
|
| 169 |
+
# objective never asked for and it overruns the clock. Win when
|
| 170 |
+
# ≥4 enemy units are killed AND your fact still stands, before
|
| 171 |
+
# tick 1600. Stalling or teching to tanks both LOSE on the clock.
|
| 172 |
description: >
|
| 173 |
+
You start with a Construction Yard, a Barracks, and $6000. A
|
| 174 |
+
light rifle garrison advances from the east. Kill four enemies
|
| 175 |
+
within about 17 turns, keeping your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
starting_cash: 6000
|
| 177 |
overrides:
|
| 178 |
actors:
|
|
|
|
| 206 |
# max_turns 30 keeps the loop alive to that terminal frame so the
|
| 207 |
# after_ticks 1401 fail bites as a real reachable LOSS.
|
| 208 |
medium:
|
| 209 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 210 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 211 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 212 |
+
#
|
| 213 |
+
# Same base (fact + tent pre-placed, e1 buildable from turn 1) but
|
| 214 |
+
# a larger enemy garrison (7 rifle infantry) and a tighter
|
| 215 |
+
# deadline. The objective still needs only basic units: train an
|
| 216 |
+
# e1 swarm and rally it at your base front. Climbing the tech
|
| 217 |
+
# chain to a war factory and tanks is an unnecessary tier that
|
| 218 |
+
# overruns the clock. Win when ≥6 enemy units are killed AND your
|
| 219 |
+
# fact still stands, before tick 1400. Stalling or teching to
|
| 220 |
+
# tanks both LOSE on the clock.
|
| 221 |
description: >
|
| 222 |
+
Same base with $6000, but seven rifle attackers and a tighter
|
| 223 |
+
clock. Kill six enemies within about 15 turns, keeping your
|
| 224 |
+
construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
starting_cash: 6000
|
| 226 |
overrides:
|
| 227 |
actors:
|
|
|
|
| 257 |
# real reachable LOSS (the old max_turns 23 hit the turn cap at
|
| 258 |
# tick ~1578 before the deadline on seeds 1/3 → degenerate draw).
|
| 259 |
hard:
|
| 260 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 261 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 262 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 263 |
+
#
|
| 264 |
+
# Same step-pruning call as medium (clear a 7-rifle garrison with
|
| 265 |
+
# a basic e1 swarm before tick 1400; skip the unnecessary war-
|
| 266 |
+
# factory tech tier) but your base may begin in the NORTH band
|
| 267 |
+
# (y≈14) or the SOUTH band (y≈26) depending on the seed. Read
|
| 268 |
+
# your barracks' actual position from the observation, train the
|
| 269 |
+
# e1 swarm and rally it at your base front. Win when ≥6 enemy
|
| 270 |
+
# units are killed AND your fact still stands, before tick 1400.
|
| 271 |
+
# Stalling or teching to tanks both LOSE on the clock.
|
| 272 |
description: >
|
| 273 |
+
Same task as medium, but your base sits in the north or south
|
| 274 |
+
band depending on seed. Kill six enemies within about 15 turns,
|
| 275 |
+
keeping your construction yard.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
starting_cash: 6000
|
| 277 |
overrides:
|
| 278 |
actors:
|
|
@@ -63,12 +63,19 @@ levels:
|
|
| 63 |
# (no tent); idle/stall loses on the clock. Generous, tick-aligned
|
| 64 |
# clock. max_turns 30 → reachable tick 93+90·29 = 2703.
|
| 65 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
description: >
|
| 67 |
-
No power is pre-placed.
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
the barracks first never completes (no power); spamming power
|
| 71 |
-
plants never gives a barracks; idling loses on the clock.
|
| 72 |
starting_cash: 6000
|
| 73 |
win_condition:
|
| 74 |
all_of:
|
|
@@ -88,13 +95,20 @@ levels:
|
|
| 88 |
# loses (not in region); idle loses on the clock.
|
| 89 |
# max_turns 40 → reachable tick 93+90·39 = 3603.
|
| 90 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
description: >
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
eastern region near (40,20). Skipping the chain never yields a
|
| 96 |
-
pillbox; placing the pillboxes near the base (wrong direction)
|
| 97 |
-
does not count; idling loses on the clock.
|
| 98 |
starting_cash: 5000
|
| 99 |
win_condition:
|
| 100 |
all_of:
|
|
@@ -114,14 +128,21 @@ levels:
|
|
| 114 |
# creep that omits the tech chain never yields a pillbox; idle loses
|
| 115 |
# on the clock. max_turns 70 → reachable tick 93+90·69 = 6303.
|
| 116 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
description: >
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
the barracks and place at least two pillboxes (pbox → tent →
|
| 122 |
-
power chain) inside the far region, before the tight deadline.
|
| 123 |
-
Building near the spawn never reaches the region; a power creep
|
| 124 |
-
that skips the barracks never yields a pillbox; idling loses.
|
| 125 |
starting_cash: 6000
|
| 126 |
win_condition:
|
| 127 |
all_of:
|
|
|
|
| 63 |
# (no tent); idle/stall loses on the clock. Generous, tick-aligned
|
| 64 |
# clock. max_turns 30 → reachable tick 93+90·29 = 2703.
|
| 65 |
easy:
|
| 66 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 67 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 68 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 69 |
+
#
|
| 70 |
+
# No power is pre-placed. Build a power plant first, THEN the
|
| 71 |
+
# power-dependent barracks (tent) — a power-less barracks never
|
| 72 |
+
# completes. Win = own a 'tent' AND ≥3 buildings total. Building
|
| 73 |
+
# the barracks first never completes (no power); spamming power
|
| 74 |
+
# plants never gives a barracks; idling loses on the clock.
|
| 75 |
description: >
|
| 76 |
+
No power is pre-placed. End up owning a Barracks (tent) and at
|
| 77 |
+
least three buildings total within about 27 turns. The barracks
|
| 78 |
+
requires power to complete.
|
|
|
|
|
|
|
| 79 |
starting_cash: 6000
|
| 80 |
win_condition:
|
| 81 |
all_of:
|
|
|
|
| 95 |
# loses (not in region); idle loses on the clock.
|
| 96 |
# max_turns 40 → reachable tick 93+90·39 = 3603.
|
| 97 |
medium:
|
| 98 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 99 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 100 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 101 |
+
#
|
| 102 |
+
# Build a defensive line to the EAST: stand up power, then the
|
| 103 |
+
# barracks it enables, then place at least two pillboxes (pbox —
|
| 104 |
+
# they need the barracks, which needs power) INSIDE the designated
|
| 105 |
+
# eastern region near (40,20). Skipping the chain never yields a
|
| 106 |
+
# pillbox; placing the pillboxes near the base (wrong direction)
|
| 107 |
+
# does not count; idling loses on the clock.
|
| 108 |
description: >
|
| 109 |
+
Place at least two pillboxes within nine cells of (40,20) — the
|
| 110 |
+
eastern region — within about 38 turns. Pillboxes need a
|
| 111 |
+
barracks, which needs power.
|
|
|
|
|
|
|
|
|
|
| 112 |
starting_cash: 5000
|
| 113 |
win_condition:
|
| 114 |
all_of:
|
|
|
|
| 128 |
# creep that omits the tech chain never yields a pillbox; idle loses
|
| 129 |
# on the clock. max_turns 70 → reachable tick 93+90·69 = 6303.
|
| 130 |
hard:
|
| 131 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 132 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 133 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 134 |
+
#
|
| 135 |
+
# Found the defensive line FAR to the east, near (60,20) — beyond
|
| 136 |
+
# the construction yard's reach. Creep the base east (each new
|
| 137 |
+
# power plant extends where you may build) until you can stand up
|
| 138 |
+
# the barracks and place at least two pillboxes (pbox → tent →
|
| 139 |
+
# power chain) inside the far region, before the tight deadline.
|
| 140 |
+
# Building near the spawn never reaches the region; a power creep
|
| 141 |
+
# that skips the barracks never yields a pillbox; idling loses.
|
| 142 |
description: >
|
| 143 |
+
Place at least two pillboxes within ten cells of (60,20) — far
|
| 144 |
+
beyond your construction yard's reach — within about 64 turns.
|
| 145 |
+
Each new building extends where you may build next.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
starting_cash: 6000
|
| 147 |
win_condition:
|
| 148 |
all_of:
|
|
@@ -164,22 +164,30 @@ levels:
|
|
| 164 |
# engaging the line). Stall LOSES (line is stance:2, never
|
| 165 |
# advances; fact never razed). Fog flank cleanly WINS.
|
| 166 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
description: >
|
| 168 |
-
Four
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
line, an UNDEFENDED enemy construction yard (fact) sits at
|
| 173 |
-
(100,20). Charging head-on (east along y=20) puts the lead
|
| 174 |
-
tank in range of all three e3 and the column burns turns
|
| 175 |
-
reducing the line — the fact at x=100 is still 50 cells away
|
| 176 |
-
with the deadline closing. The winning play is the FOG FLANK
|
| 177 |
-
— route the strike force to the far north (y=2) or far south
|
| 178 |
-
(y=38), well outside the line's range, drive east past x=80,
|
| 179 |
-
then turn inward to descend on the fact at (100,20). Win
|
| 180 |
-
when the fact at (100,20) is destroyed AND ≥2 of your tanks
|
| 181 |
-
survive, before tick 5400. Stalling LOSES (fact never
|
| 182 |
-
destroyed); frontal-charge LOSES on the clock.
|
| 183 |
overrides:
|
| 184 |
actors:
|
| 185 |
# STRIKE FORCE — 4 medium tanks stacked at the west edge,
|
|
@@ -222,23 +230,31 @@ levels:
|
|
| 222 |
# wins comfortably: the line never fires on the flanker (Manhattan
|
| 223 |
# ≥13 to the nearest defender from y=2 or y=38).
|
| 224 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
description: >
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
Dragon range ~5). Behind the line, an UNDEFENDED enemy
|
| 231 |
-
construction yard (fact) sits at (100,20). Charging head-on
|
| 232 |
-
(east along y=18..22) puts the lead tank inside the
|
| 233 |
-
overlapping kill envelopes of 4+ defenders simultaneously;
|
| 234 |
-
concentrated fire destroys the column before it clears.
|
| 235 |
-
The winning play is the FOG FLANK — route the strike force
|
| 236 |
-
WELL off-axis to the far north (y=2) or far south (y=38),
|
| 237 |
-
drive east past the line's longitude (x=50), then turn
|
| 238 |
-
inward to descend on the fact at (100,20) from behind. Win
|
| 239 |
-
when the fact at (100,20) is destroyed AND ≥2 of your tanks
|
| 240 |
-
survive, before tick 4500. Stall, brute attack_move east,
|
| 241 |
-
and any frontal charge all LOSE.
|
| 242 |
overrides:
|
| 243 |
actors:
|
| 244 |
- {type: 2tnk, owner: agent, position: [6, 18], stance: 1}
|
|
@@ -293,24 +309,33 @@ levels:
|
|
| 293 |
# fog-flank decision (NORTH spawn → fog via y=2; SOUTH spawn
|
| 294 |
# → fog via y=38).
|
| 295 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
description: >
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
tank rocket soldiers (e3, Dragon launcher, range ~5). Behind
|
| 303 |
-
the wall, an UNDEFENDED enemy construction yard (fact) sits
|
| 304 |
-
at (100,20). Any frontal charge along y=14..26 enters the
|
| 305 |
-
overlapping kill envelope of the entire 10-defender wall;
|
| 306 |
-
concentrated fire destroys the column before it clears.
|
| 307 |
-
The winning play is the FOG FLANK — route the strike force
|
| 308 |
-
to the far north (y=2 from the NORTH spawn) or far south
|
| 309 |
-
(y=38 from the SOUTH spawn), drive east past x=80, then
|
| 310 |
-
turn inward to descend on the fact at (100,20). Win when
|
| 311 |
-
the fact at (100,20) is destroyed AND ≥2 of your tanks
|
| 312 |
-
survive, before tick 4500. Stall, brute attack_move east,
|
| 313 |
-
and any frontal head-on charge all LOSE.
|
| 314 |
overrides:
|
| 315 |
actors:
|
| 316 |
# spawn_point 0 — NORTH staging corridor (y=14..17). Fog
|
|
|
|
| 164 |
# engaging the line). Stall LOSES (line is stance:2, never
|
| 165 |
# advances; fact never razed). Fog flank cleanly WINS.
|
| 166 |
easy:
|
| 167 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 168 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 169 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 170 |
+
#
|
| 171 |
+
# Four medium tanks (2tnk) stage at the west edge (x=6, y=18..21).
|
| 172 |
+
# A LIGHT vertical line of THREE anti-tank rocket soldiers (e3,
|
| 173 |
+
# Dragon launcher, range ~5) stands at x=50, y=19..21, facing
|
| 174 |
+
# west (stance:2 — auto-fire in range, no chase). Behind the
|
| 175 |
+
# line, an UNDEFENDED enemy construction yard (fact) sits at
|
| 176 |
+
# (100,20). Charging head-on (east along y=20) puts the lead
|
| 177 |
+
# tank in range of all three e3 and the column burns turns
|
| 178 |
+
# reducing the line — the fact at x=100 is still 50 cells away
|
| 179 |
+
# with the deadline closing. The winning play is the FOG FLANK
|
| 180 |
+
# — route the strike force to the far north (y=2) or far south
|
| 181 |
+
# (y=38), well outside the line's range, drive east past x=80,
|
| 182 |
+
# then turn inward to descend on the fact at (100,20). Win
|
| 183 |
+
# when the fact at (100,20) is destroyed AND ≥2 of your tanks
|
| 184 |
+
# survive, before tick 5400. Stalling LOSES (fact never
|
| 185 |
+
# destroyed); frontal-charge LOSES on the clock.
|
| 186 |
description: >
|
| 187 |
+
Four tanks stage at the west edge. A light rocket-infantry line
|
| 188 |
+
at x=50 blocks the centre; the enemy construction yard at
|
| 189 |
+
(100,20) is undefended. Destroy the yard with at least two tanks
|
| 190 |
+
surviving, within about 65 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
overrides:
|
| 192 |
actors:
|
| 193 |
# STRIKE FORCE — 4 medium tanks stacked at the west edge,
|
|
|
|
| 230 |
# wins comfortably: the line never fires on the flanker (Manhattan
|
| 231 |
# ≥13 to the nearest defender from y=2 or y=38).
|
| 232 |
medium:
|
| 233 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 234 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 235 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 236 |
+
#
|
| 237 |
+
# Four medium tanks (2tnk) stage at the west edge (x=6, y=18..21).
|
| 238 |
+
# A HEAVY defensive line stands at x=50, y=15..25, facing west
|
| 239 |
+
# (stance:2 — auto-fire in range, no chase): TWO pillboxes
|
| 240 |
+
# (pbox, range ~6) bookend FIVE anti-tank rocket soldiers (e3,
|
| 241 |
+
# Dragon range ~5). Behind the line, an UNDEFENDED enemy
|
| 242 |
+
# construction yard (fact) sits at (100,20). Charging head-on
|
| 243 |
+
# (east along y=18..22) puts the lead tank inside the
|
| 244 |
+
# overlapping kill envelopes of 4+ defenders simultaneously;
|
| 245 |
+
# concentrated fire destroys the column before it clears.
|
| 246 |
+
# The winning play is the FOG FLANK — route the strike force
|
| 247 |
+
# WELL off-axis to the far north (y=2) or far south (y=38),
|
| 248 |
+
# drive east past the line's longitude (x=50), then turn
|
| 249 |
+
# inward to descend on the fact at (100,20) from behind. Win
|
| 250 |
+
# when the fact at (100,20) is destroyed AND ≥2 of your tanks
|
| 251 |
+
# survive, before tick 4500. Stall, brute attack_move east,
|
| 252 |
+
# and any frontal charge all LOSE.
|
| 253 |
description: >
|
| 254 |
+
Heavier line at x=50: two pillboxes plus five rocket soldiers
|
| 255 |
+
spanning y=15 to 25. The enemy construction yard at (100,20)
|
| 256 |
+
remains undefended. Destroy the yard with at least two tanks
|
| 257 |
+
surviving, within about 54 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
overrides:
|
| 259 |
actors:
|
| 260 |
- {type: 2tnk, owner: agent, position: [6, 18], stance: 1}
|
|
|
|
| 309 |
# fog-flank decision (NORTH spawn → fog via y=2; SOUTH spawn
|
| 310 |
# → fog via y=38).
|
| 311 |
hard:
|
| 312 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 313 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 314 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 315 |
+
#
|
| 316 |
+
# Four medium tanks (2tnk) stage at ONE of two west-edge
|
| 317 |
+
# corridors (NORTH y=14..17 OR SOUTH y=23..26, chosen by seed,
|
| 318 |
+
# anti-memorisation). A dense vertical wall stands at x=50,
|
| 319 |
+
# y=15..25, facing west (stance:2 — auto-fire in range, no
|
| 320 |
+
# chase): THREE pillboxes (pbox) interleaved with SEVEN anti-
|
| 321 |
+
# tank rocket soldiers (e3, Dragon launcher, range ~5). Behind
|
| 322 |
+
# the wall, an UNDEFENDED enemy construction yard (fact) sits
|
| 323 |
+
# at (100,20). Any frontal charge along y=14..26 enters the
|
| 324 |
+
# overlapping kill envelope of the entire 10-defender wall;
|
| 325 |
+
# concentrated fire destroys the column before it clears.
|
| 326 |
+
# The winning play is the FOG FLANK — route the strike force
|
| 327 |
+
# to the far north (y=2 from the NORTH spawn) or far south
|
| 328 |
+
# (y=38 from the SOUTH spawn), drive east past x=80, then
|
| 329 |
+
# turn inward to descend on the fact at (100,20). Win when
|
| 330 |
+
# the fact at (100,20) is destroyed AND ≥2 of your tanks
|
| 331 |
+
# survive, before tick 4500. Stall, brute attack_move east,
|
| 332 |
+
# and any frontal head-on charge all LOSE.
|
| 333 |
description: >
|
| 334 |
+
Same task as medium with a denser wall (three pillboxes plus
|
| 335 |
+
seven rocket soldiers at x=50). Your tanks stage in the north
|
| 336 |
+
or south corridor depending on seed. Destroy the enemy yard at
|
| 337 |
+
(100,20) with at least two tanks surviving, within about 54
|
| 338 |
+
turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
overrides:
|
| 340 |
actors:
|
| 341 |
# spawn_point 0 — NORTH staging corridor (y=14..17). Fog
|
|
@@ -111,19 +111,26 @@ levels:
|
|
| 111 |
# them at their leash the strike tanks focus-fire the nearest guard
|
| 112 |
# and then drive onto the now-undefended yard.
|
| 113 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
description: >
|
| 115 |
-
Three leashed rocket-infantry guards
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
units in range, lunge at the nearest foe within ≈16 cells, and
|
| 119 |
-
snap back past a leash of ≈18. Destroy the enemy construction
|
| 120 |
-
yard with at most 3 of your units lost before tick 5400.
|
| 121 |
-
Driving the tanks straight east at the yard puts them in
|
| 122 |
-
anti-tank fire from the whole guard line; stalling runs the
|
| 123 |
-
clock. Commit the fast jeep on a divergent south-east vector
|
| 124 |
-
so the guards lunge south after it; while the jeep kites them
|
| 125 |
-
at their leash, run the strike tanks straight through the
|
| 126 |
-
now-undefended west face to destroy the yard.
|
| 127 |
overrides:
|
| 128 |
actors:
|
| 129 |
# Strike force: 4 medium tanks at west, central staging.
|
|
@@ -175,19 +182,26 @@ levels:
|
|
| 175 |
# jeep + at most one tank): the strike must still hit the yard
|
| 176 |
# essentially intact; burning a second tank fails.
|
| 177 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
description: >
|
| 179 |
-
|
| 180 |
-
the enemy
|
| 181 |
-
|
| 182 |
-
A head-on push without first thinning the cover is decisively
|
| 183 |
-
fatal. You command 5 medium tanks staged on the NORTH flank
|
| 184 |
-
plus the bait jeep, but may spend at most 2 units — losing a
|
| 185 |
-
second tank fails. Commit the fast jeep on a deep south flank
|
| 186 |
-
vector to pull the south arc of guards off post after it; while
|
| 187 |
-
that arc is displaced, swing the strike tanks around the
|
| 188 |
-
now-vacated NORTH flank and onto the yard before tick 5400.
|
| 189 |
-
Bait-only (no strike) loses on the clock; brute frontal trades
|
| 190 |
-
the strike force.
|
| 191 |
overrides:
|
| 192 |
actors:
|
| 193 |
# Strike force: 5 medium tanks staged on the NORTH flank
|
|
@@ -234,20 +248,27 @@ levels:
|
|
| 234 |
# closer guard arc engages the column before the bait can pull it).
|
| 235 |
# Same 5-guard L cover, 5-tank strike, and loss cap 2 as medium.
|
| 236 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
description: >
|
| 238 |
-
|
| 239 |
-
(
|
| 240 |
-
|
| 241 |
-
forward — so a memorised fixed opening cannot generalise; read
|
| 242 |
-
your tanks' actual position from the observation. You command 5
|
| 243 |
-
medium tanks staged on the NORTH flank plus the bait jeep, but
|
| 244 |
-
may spend at most 2 units (the jeep + at most one tank) —
|
| 245 |
-
losing a second tank fails. Commit the fast jeep on a deep
|
| 246 |
-
south flank vector to pull the south arc of guards off post;
|
| 247 |
-
while that arc is displaced, swing the strike tanks around the
|
| 248 |
-
now-vacated NORTH flank and onto the yard before tick 5400.
|
| 249 |
-
Brute frontal trades armour and fails; bait-only never razes
|
| 250 |
-
the yard; stalling loses the clock.
|
| 251 |
overrides:
|
| 252 |
actors:
|
| 253 |
# spawn_point 0 — FAR-WEST staging (x=6): the strike has the
|
|
|
|
| 111 |
# them at their leash the strike tanks focus-fire the nearest guard
|
| 112 |
# and then drive onto the now-undefended yard.
|
| 113 |
easy:
|
| 114 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 115 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 116 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 117 |
+
#
|
| 118 |
+
# Three leashed rocket-infantry guards stand on the west face of
|
| 119 |
+
# the enemy construction yard (`fact` at 80,20), directly
|
| 120 |
+
# between you and the objective. They hold post, auto-fire on
|
| 121 |
+
# units in range, lunge at the nearest foe within ≈16 cells, and
|
| 122 |
+
# snap back past a leash of ≈18. Destroy the enemy construction
|
| 123 |
+
# yard with at most 3 of your units lost before tick 5400.
|
| 124 |
+
# Driving the tanks straight east at the yard puts them in
|
| 125 |
+
# anti-tank fire from the whole guard line; stalling runs the
|
| 126 |
+
# clock. Commit the fast jeep on a divergent south-east vector
|
| 127 |
+
# so the guards lunge south after it; while the jeep kites them
|
| 128 |
+
# at their leash, run the strike tanks straight through the
|
| 129 |
+
# now-undefended west face to destroy the yard.
|
| 130 |
description: >
|
| 131 |
+
Three leashed rocket-infantry guards wall the west face of the
|
| 132 |
+
enemy construction yard at (80,20). Destroy the yard, losing at
|
| 133 |
+
most three units, within about 62 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
overrides:
|
| 135 |
actors:
|
| 136 |
# Strike force: 4 medium tanks at west, central staging.
|
|
|
|
| 182 |
# jeep + at most one tank): the strike must still hit the yard
|
| 183 |
# essentially intact; burning a second tank fails.
|
| 184 |
medium:
|
| 185 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 186 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 187 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 188 |
+
#
|
| 189 |
+
# A denser cluster of 5 leashed rocket-infantry guards covers
|
| 190 |
+
# the enemy construction yard (`fact` at 80,20) on the WEST and
|
| 191 |
+
# SOUTH faces (the two natural approaches from your west base).
|
| 192 |
+
# A head-on push without first thinning the cover is decisively
|
| 193 |
+
# fatal. You command 5 medium tanks staged on the NORTH flank
|
| 194 |
+
# plus the bait jeep, but may spend at most 2 units — losing a
|
| 195 |
+
# second tank fails. Commit the fast jeep on a deep south flank
|
| 196 |
+
# vector to pull the south arc of guards off post after it; while
|
| 197 |
+
# that arc is displaced, swing the strike tanks around the
|
| 198 |
+
# now-vacated NORTH flank and onto the yard before tick 5400.
|
| 199 |
+
# Bait-only (no strike) loses on the clock; brute frontal trades
|
| 200 |
+
# the strike force.
|
| 201 |
description: >
|
| 202 |
+
Denser cover — five leashed rocket-infantry guards on the west
|
| 203 |
+
and south faces of the enemy yard at (80,20). Destroy the yard,
|
| 204 |
+
losing at most two units, within about 62 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
overrides:
|
| 206 |
actors:
|
| 207 |
# Strike force: 5 medium tanks staged on the NORTH flank
|
|
|
|
| 248 |
# closer guard arc engages the column before the bait can pull it).
|
| 249 |
# Same 5-guard L cover, 5-tank strike, and loss cap 2 as medium.
|
| 250 |
hard:
|
| 251 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 252 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 253 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 254 |
+
#
|
| 255 |
+
# The same dense 5-guard L-cover of the enemy construction yard
|
| 256 |
+
# (`fact` at 80,20) as the previous tier, but your force stages
|
| 257 |
+
# from a seed-chosen distance — either the far west or well
|
| 258 |
+
# forward — so a memorised fixed opening cannot generalise; read
|
| 259 |
+
# your tanks' actual position from the observation. You command 5
|
| 260 |
+
# medium tanks staged on the NORTH flank plus the bait jeep, but
|
| 261 |
+
# may spend at most 2 units (the jeep + at most one tank) —
|
| 262 |
+
# losing a second tank fails. Commit the fast jeep on a deep
|
| 263 |
+
# south flank vector to pull the south arc of guards off post;
|
| 264 |
+
# while that arc is displaced, swing the strike tanks around the
|
| 265 |
+
# now-vacated NORTH flank and onto the yard before tick 5400.
|
| 266 |
+
# Brute frontal trades armour and fails; bait-only never razes
|
| 267 |
+
# the yard; stalling loses the clock.
|
| 268 |
description: >
|
| 269 |
+
Same task as medium, but your force stages from a seed-chosen
|
| 270 |
+
distance (far west or well forward). Destroy the enemy yard,
|
| 271 |
+
losing at most two units, within about 62 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
overrides:
|
| 273 |
actors:
|
| 274 |
# spawn_point 0 — FAR-WEST staging (x=6): the strike has the
|
|
@@ -142,18 +142,26 @@ levels:
|
|
| 142 |
# inert-easy-teeth convention — the divide-vs-converge delta lives
|
| 143 |
# on medium and hard).
|
| 144 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
description: >
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
apart — engaging on the y=20 midpoint puts you in range of
|
| 151 |
-
both at once. The winning play is divide-and-conquer: flank
|
| 152 |
-
one cluster (e.g. via y=5 or y=35), eliminate it, then pivot
|
| 153 |
-
to the other. Your construction yard (fact) sits at the deep
|
| 154 |
-
rear (4,20); it must survive. Win when 4 enemies are killed,
|
| 155 |
-
at least 3 of your tanks remain, your fact still stands, and
|
| 156 |
-
the deadline (tick 4500) has not passed.
|
| 157 |
overrides:
|
| 158 |
actors:
|
| 159 |
# STRIKE FORCE — 4 medium tanks at the west edge, stance:1
|
|
@@ -206,19 +214,26 @@ levels:
|
|
| 206 |
# one cluster at a time in clean 1-vs-1-cluster geometry, preserving
|
| 207 |
# all 4 tanks.
|
| 208 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
description: >
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
tank) and a SOUTH cluster at y=25 (same). The clusters are
|
| 214 |
-
10 cells apart — engaging on the y=20 midpoint puts you inside
|
| 215 |
-
weapon range of BOTH clusters at once (8 enemies firing on the
|
| 216 |
-
lead). The winning play is divide-and-conquer: flank well
|
| 217 |
-
NORTH (e.g. y=5) so only Cluster A is in range, eliminate it,
|
| 218 |
-
then pivot SOUTH (e.g. y=35) and engage Cluster B in isolation.
|
| 219 |
-
Your construction yard (fact) at (4,20) must survive. Win when
|
| 220 |
-
8 enemies are killed, at least 3 of your tanks remain, your
|
| 221 |
-
fact still stands, and the deadline (tick 4500) has not passed.
|
| 222 |
overrides:
|
| 223 |
actors:
|
| 224 |
- {type: 2tnk, owner: agent, position: [6, 18], stance: 1}
|
|
@@ -269,20 +284,28 @@ levels:
|
|
| 269 |
# The survival cap also tightens to own_units_gte:3 (only 1 tank
|
| 270 |
# may be lost across the whole campaign on hard).
|
| 271 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
description: >
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
cluster at y=25 (same). The clusters are 10 cells apart —
|
| 278 |
-
engaging on the y=20 midpoint puts you inside weapon range of
|
| 279 |
-
BOTH clusters at once (8 enemies firing on the lead). The
|
| 280 |
-
winning play is divide-and-conquer: flank well NORTH (y=5) or
|
| 281 |
-
SOUTH (y=35) so only ONE cluster is in range, eliminate it,
|
| 282 |
-
then pivot to the OTHER side and engage the second cluster
|
| 283 |
-
in isolation. Your construction yard (fact) at (4,20) must
|
| 284 |
-
survive. Win when 8 enemies are killed, at least 3 of your
|
| 285 |
-
tanks remain, your fact still stands, before tick 4500.
|
| 286 |
overrides:
|
| 287 |
actors:
|
| 288 |
# spawn_point 0 — NORTH staging corridor y=10..13. Closer
|
|
|
|
| 142 |
# inert-easy-teeth convention — the divide-vs-converge delta lives
|
| 143 |
# on medium and hard).
|
| 144 |
easy:
|
| 145 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 146 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 147 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 148 |
+
#
|
| 149 |
+
# You command 4 medium tanks (2tnk) staging at the west edge
|
| 150 |
+
# (x=6, y=18..21). Two enemy clusters sit at x=60: a NORTH
|
| 151 |
+
# cluster at y=15 (2× e3 anti-tank rocketeers, range ~5) and
|
| 152 |
+
# a SOUTH cluster at y=25 (same). The clusters are 10 cells
|
| 153 |
+
# apart — engaging on the y=20 midpoint puts you in range of
|
| 154 |
+
# both at once. The winning play is divide-and-conquer: flank
|
| 155 |
+
# one cluster (e.g. via y=5 or y=35), eliminate it, then pivot
|
| 156 |
+
# to the other. Your construction yard (fact) sits at the deep
|
| 157 |
+
# rear (4,20); it must survive. Win when 4 enemies are killed,
|
| 158 |
+
# at least 3 of your tanks remain, your fact still stands, and
|
| 159 |
+
# the deadline (tick 4500) has not passed.
|
| 160 |
description: >
|
| 161 |
+
Four tanks at the west edge. Two enemy rocket-infantry clusters
|
| 162 |
+
sit at x=60, ten cells apart at y=15 and y=25. Kill four
|
| 163 |
+
enemies, keep at least three tanks and your construction yard,
|
| 164 |
+
within about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
overrides:
|
| 166 |
actors:
|
| 167 |
# STRIKE FORCE — 4 medium tanks at the west edge, stance:1
|
|
|
|
| 214 |
# one cluster at a time in clean 1-vs-1-cluster geometry, preserving
|
| 215 |
# all 4 tanks.
|
| 216 |
medium:
|
| 217 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 218 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 219 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 220 |
+
#
|
| 221 |
+
# You command 4 medium tanks (2tnk) staging at the west edge
|
| 222 |
+
# (x=6, y=18..21). Two HEAVY enemy clusters sit at x=60: a NORTH
|
| 223 |
+
# cluster at y=15 (3× e3 anti-tank rocketeers + 1× 1tnk light
|
| 224 |
+
# tank) and a SOUTH cluster at y=25 (same). The clusters are
|
| 225 |
+
# 10 cells apart — engaging on the y=20 midpoint puts you inside
|
| 226 |
+
# weapon range of BOTH clusters at once (8 enemies firing on the
|
| 227 |
+
# lead). The winning play is divide-and-conquer: flank well
|
| 228 |
+
# NORTH (e.g. y=5) so only Cluster A is in range, eliminate it,
|
| 229 |
+
# then pivot SOUTH (e.g. y=35) and engage Cluster B in isolation.
|
| 230 |
+
# Your construction yard (fact) at (4,20) must survive. Win when
|
| 231 |
+
# 8 enemies are killed, at least 3 of your tanks remain, your
|
| 232 |
+
# fact still stands, and the deadline (tick 4500) has not passed.
|
| 233 |
description: >
|
| 234 |
+
Heavier clusters at y=15 and y=25 (rocket soldiers plus a light
|
| 235 |
+
tank each, eight enemies total). Kill all eight, keep at least
|
| 236 |
+
three tanks and your construction yard, within about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
overrides:
|
| 238 |
actors:
|
| 239 |
- {type: 2tnk, owner: agent, position: [6, 18], stance: 1}
|
|
|
|
| 284 |
# The survival cap also tightens to own_units_gte:3 (only 1 tank
|
| 285 |
# may be lost across the whole campaign on hard).
|
| 286 |
hard:
|
| 287 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 288 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 289 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 290 |
+
#
|
| 291 |
+
# You command 4 medium tanks (2tnk) staging at ONE of two west-
|
| 292 |
+
# edge corridors (NORTH y=10..13 or SOUTH y=27..30, chosen by
|
| 293 |
+
# seed). Two HEAVY enemy clusters sit at x=60: a NORTH cluster
|
| 294 |
+
# at y=15 (3× e3 anti-tank rocketeers + 1× 1tnk) and a SOUTH
|
| 295 |
+
# cluster at y=25 (same). The clusters are 10 cells apart —
|
| 296 |
+
# engaging on the y=20 midpoint puts you inside weapon range of
|
| 297 |
+
# BOTH clusters at once (8 enemies firing on the lead). The
|
| 298 |
+
# winning play is divide-and-conquer: flank well NORTH (y=5) or
|
| 299 |
+
# SOUTH (y=35) so only ONE cluster is in range, eliminate it,
|
| 300 |
+
# then pivot to the OTHER side and engage the second cluster
|
| 301 |
+
# in isolation. Your construction yard (fact) at (4,20) must
|
| 302 |
+
# survive. Win when 8 enemies are killed, at least 3 of your
|
| 303 |
+
# tanks remain, your fact still stands, before tick 4500.
|
| 304 |
description: >
|
| 305 |
+
Same heavy clusters as medium, but your tanks stage in the north
|
| 306 |
+
or south corridor depending on seed. Kill all eight enemies, keep
|
| 307 |
+
at least three tanks and your construction yard, within about
|
| 308 |
+
50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
overrides:
|
| 310 |
actors:
|
| 311 |
# spawn_point 0 — NORTH staging corridor y=10..13. Closer
|
|
@@ -130,20 +130,27 @@ levels:
|
|
| 130 |
# the lead, just under one-shot range). Stall LOSES on the clock
|
| 131 |
# (defenders are stance:2 ReturnFire-equivalent, never advance).
|
| 132 |
easy:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
description: >
|
| 134 |
-
Four
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
west (stance:2 — auto-fire in range, no chase). Charging
|
| 138 |
-
head-on (east along y=20) puts the lead tank in range of all
|
| 139 |
-
three rocket soldiers at once. The winning play is the FLANK
|
| 140 |
-
— move the strike force off-axis (north of y=18 or south of
|
| 141 |
-
y=22) and approach the line end-on so only 1-2 rocket
|
| 142 |
-
soldiers are in range at any moment. Win when 3 enemy units
|
| 143 |
-
are killed AND at least 3 of your tanks remain, before tick
|
| 144 |
-
4500. Stalling LOSES (kill bar unmet). Brute attack_move east
|
| 145 |
-
can squeak the survival bar on easy — the bigger tests are
|
| 146 |
-
on medium and hard.
|
| 147 |
overrides:
|
| 148 |
actors:
|
| 149 |
# STRIKE FORCE — 4 medium tanks stacked at the west edge,
|
|
@@ -183,21 +190,28 @@ levels:
|
|
| 183 |
# all 4 tanks because only 1-2 e3 are ever in range of the leading
|
| 184 |
# flanker at a time.
|
| 185 |
medium:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
description: >
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
west (stance:2 — auto-fire in range, no chase). Charging
|
| 191 |
-
head-on along the engagement axis (y=20) puts the lead tank
|
| 192 |
-
inside range of ALL FIVE rocket soldiers simultaneously —
|
| 193 |
-
concentrated fire pressures the column. The winning play is
|
| 194 |
-
the FLANK — move the strike force off-axis (well NORTH of
|
| 195 |
-
y=18 or well SOUTH of y=22, e.g. y=8 or y=32) and approach
|
| 196 |
-
the line END-ON so only one or two rocket soldiers are in
|
| 197 |
-
Dragon range of the leading flanker at any moment; pick them
|
| 198 |
-
off in sequence. Win when 4 enemy units are killed AND at
|
| 199 |
-
least 3 of your tanks remain, before tick 4500. Stall and
|
| 200 |
-
brute attack_move east both LOSE.
|
| 201 |
overrides:
|
| 202 |
actors:
|
| 203 |
- {type: 2tnk, owner: agent, position: [6, 18], stance: 1}
|
|
@@ -241,24 +255,31 @@ levels:
|
|
| 241 |
# symmetric across the map's mid-latitude (y=20) so either
|
| 242 |
# spawn faces an equivalent flank decision.
|
| 243 |
hard:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
description: >
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
soldiers (e3, Dragon launcher, range ~5) — SIX in the front
|
| 249 |
-
rank at x=60 (y=17..22) and FOUR in a back rank at x=62 —
|
| 250 |
-
stands facing west (stance:2 — auto-fire in range, no
|
| 251 |
-
chase). Charging east along any engagement axis between y=14
|
| 252 |
-
and y=26 puts the lead tank inside Dragon range of MOST of
|
| 253 |
-
the 10-e3 wall ⇒ concentrated rocket fire destroys ≥1 tank
|
| 254 |
-
before the column clears the line. The winning play is the
|
| 255 |
-
FLANK — approach from WELL off-axis (y=8 from the north
|
| 256 |
-
spawn or y=32 from the south spawn) and engage the line
|
| 257 |
-
END-ON so only one or two rocket soldiers are in range of
|
| 258 |
-
the leading flanker at any moment. Win when 4 enemy units
|
| 259 |
-
are killed AND ALL FOUR of your tanks remain, before tick
|
| 260 |
-
4500. Stall, brute attack_move east, and any frontal head-on
|
| 261 |
-
charge all LOSE.
|
| 262 |
overrides:
|
| 263 |
actors:
|
| 264 |
# spawn_point 0 — NORTH staging corridor (y=14..17). Closer
|
|
|
|
| 130 |
# the lead, just under one-shot range). Stall LOSES on the clock
|
| 131 |
# (defenders are stance:2 ReturnFire-equivalent, never advance).
|
| 132 |
easy:
|
| 133 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 134 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 135 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 136 |
+
#
|
| 137 |
+
# Four medium tanks (2tnk) stage at the west edge (x=6, y=18..21).
|
| 138 |
+
# A short vertical line of THREE anti-tank rocket soldiers (e3,
|
| 139 |
+
# Dragon launcher, range ~5) stands at x=60, y=19..21, facing
|
| 140 |
+
# west (stance:2 — auto-fire in range, no chase). Charging
|
| 141 |
+
# head-on (east along y=20) puts the lead tank in range of all
|
| 142 |
+
# three rocket soldiers at once. The winning play is the FLANK
|
| 143 |
+
# — move the strike force off-axis (north of y=18 or south of
|
| 144 |
+
# y=22) and approach the line end-on so only 1-2 rocket
|
| 145 |
+
# soldiers are in range at any moment. Win when 3 enemy units
|
| 146 |
+
# are killed AND at least 3 of your tanks remain, before tick
|
| 147 |
+
# 4500. Stalling LOSES (kill bar unmet). Brute attack_move east
|
| 148 |
+
# can squeak the survival bar on easy — the bigger tests are
|
| 149 |
+
# on medium and hard.
|
| 150 |
description: >
|
| 151 |
+
Four tanks at the west edge face a short vertical line of three
|
| 152 |
+
rocket soldiers at x=60. Kill three enemies, keep at least three
|
| 153 |
+
tanks, within about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
overrides:
|
| 155 |
actors:
|
| 156 |
# STRIKE FORCE — 4 medium tanks stacked at the west edge,
|
|
|
|
| 190 |
# all 4 tanks because only 1-2 e3 are ever in range of the leading
|
| 191 |
# flanker at a time.
|
| 192 |
medium:
|
| 193 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 194 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 195 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 196 |
+
#
|
| 197 |
+
# Four medium tanks (2tnk) stage at the west edge (x=6, y=18..21).
|
| 198 |
+
# A tight vertical line of FIVE anti-tank rocket soldiers (e3,
|
| 199 |
+
# Dragon launcher, range ~5) stands at x=60, y=18..22, facing
|
| 200 |
+
# west (stance:2 — auto-fire in range, no chase). Charging
|
| 201 |
+
# head-on along the engagement axis (y=20) puts the lead tank
|
| 202 |
+
# inside range of ALL FIVE rocket soldiers simultaneously —
|
| 203 |
+
# concentrated fire pressures the column. The winning play is
|
| 204 |
+
# the FLANK — move the strike force off-axis (well NORTH of
|
| 205 |
+
# y=18 or well SOUTH of y=22, e.g. y=8 or y=32) and approach
|
| 206 |
+
# the line END-ON so only one or two rocket soldiers are in
|
| 207 |
+
# Dragon range of the leading flanker at any moment; pick them
|
| 208 |
+
# off in sequence. Win when 4 enemy units are killed AND at
|
| 209 |
+
# least 3 of your tanks remain, before tick 4500. Stall and
|
| 210 |
+
# brute attack_move east both LOSE.
|
| 211 |
description: >
|
| 212 |
+
Tighter five-rocket-soldier line at x=60 spanning y=18 to 22.
|
| 213 |
+
Kill four enemies, keep at least three tanks, within about 50
|
| 214 |
+
turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
overrides:
|
| 216 |
actors:
|
| 217 |
- {type: 2tnk, owner: agent, position: [6, 18], stance: 1}
|
|
|
|
| 255 |
# symmetric across the map's mid-latitude (y=20) so either
|
| 256 |
# spawn faces an equivalent flank decision.
|
| 257 |
hard:
|
| 258 |
+
# Original (pre-verbosity-sweep) description preserved for
|
| 259 |
+
# contributors. The trimmed version below removes scripted-policy
|
| 260 |
+
# spoilers and cell-coord dumps; load-bearing intent kept.
|
| 261 |
+
#
|
| 262 |
+
# Four medium tanks (2tnk) stage at ONE of two west-edge
|
| 263 |
+
# corridors (NORTH y=14..17 OR SOUTH y=23..26, chosen by seed,
|
| 264 |
+
# anti-memorisation). A two-column wall of anti-tank rocket
|
| 265 |
+
# soldiers (e3, Dragon launcher, range ~5) — SIX in the front
|
| 266 |
+
# rank at x=60 (y=17..22) and FOUR in a back rank at x=62 —
|
| 267 |
+
# stands facing west (stance:2 — auto-fire in range, no
|
| 268 |
+
# chase). Charging east along any engagement axis between y=14
|
| 269 |
+
# and y=26 puts the lead tank inside Dragon range of MOST of
|
| 270 |
+
# the 10-e3 wall ⇒ concentrated rocket fire destroys ≥1 tank
|
| 271 |
+
# before the column clears the line. The winning play is the
|
| 272 |
+
# FLANK — approach from WELL off-axis (y=8 from the north
|
| 273 |
+
# spawn or y=32 from the south spawn) and engage the line
|
| 274 |
+
# END-ON so only one or two rocket soldiers are in range of
|
| 275 |
+
# the leading flanker at any moment. Win when 4 enemy units
|
| 276 |
+
# are killed AND ALL FOUR of your tanks remain, before tick
|
| 277 |
+
# 4500. Stall, brute attack_move east, and any frontal head-on
|
| 278 |
+
# charge all LOSE.
|
| 279 |
description: >
|
| 280 |
+
Two-column rocket-soldier wall at x=60 (ten enemies total). Tanks
|
| 281 |
+
stage in the north or south corridor depending on seed. Kill
|
| 282 |
+
five enemies, keep at least three tanks, within about 50 turns.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
overrides:
|
| 284 |
actors:
|
| 285 |
# spawn_point 0 — NORTH staging corridor (y=14..17). Closer
|
|
@@ -0,0 +1,2046 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# def-bridge-chokepoint — chokepoint defense at narrow bridges.
|
| 2 |
+
# Generated; do not edit the actors/water_cells blocks by hand.
|
| 3 |
+
#
|
| 4 |
+
# Design: medium + hard each place ONE proc directly behind each bridge
|
| 5 |
+
# as the per-bridge target. An undefended bridge = its proc falls = LOSS
|
| 6 |
+
# (the win predicate requires ALL procs alive). Easy uses single-fact
|
| 7 |
+
# target because there's only one bridge.
|
| 8 |
+
#
|
| 9 |
+
# ⚠ Status (2026-05-23):
|
| 10 |
+
# easy tier: scripted-policy bar HOLDS clean — stall LOSS, intended
|
| 11 |
+
# (set_stance + attack_move to bridge) WIN.
|
| 12 |
+
# medium tier: bar holds — stall LOSS, only-centre LOSS (one proc
|
| 13 |
+
# falls), split-all WIN.
|
| 14 |
+
# hard tier: only-centre still WRONGLY wins (kill=16, all procs
|
| 15 |
+
# alive). Root cause: enemy stance:3 (AttackAnything)
|
| 16 |
+
# prefers fighting visible UNITS over buildings, so
|
| 17 |
+
# attackers from the outer bridges converge on the
|
| 18 |
+
# central defender cluster instead of marching to their
|
| 19 |
+
# designated proc. The defender column en route to the
|
| 20 |
+
# centre intercepts them all. FIX (engine, Phase 1):
|
| 21 |
+
# add `ScriptedBehavior::BuildingRusher` (variant of
|
| 22 |
+
# Rusher that explicitly attack-orders the nearest
|
| 23 |
+
# AGENT BUILDING per unit, not the nearest agent unit),
|
| 24 |
+
# then switch this pack's `enemy: {bot_type:
|
| 25 |
+
# building_rusher}` for medium + hard. Until then, hard
|
| 26 |
+
# tier should not be promoted to the active eval suite.
|
| 27 |
+
meta:
|
| 28 |
+
id: def-bridge-chokepoint
|
| 29 |
+
title: Bridge Chokepoint — defend every crossing before they reach you
|
| 30 |
+
capability: action
|
| 31 |
+
real_world_meaning: Geographic chokepoint defense. A barrier (water) channels every attacker through a small number of crossings
|
| 32 |
+
(bridges). The defender must (a) flip the engagement stance so units fire, AND (b) distribute forces across every crossing
|
| 33 |
+
— concentrating on one bridge leaves the others wide open and their assets fall.
|
| 34 |
+
robotics_analogue: Perimeter defense around a facility with a moat and discrete gates. Guards posted on standby must be
|
| 35 |
+
told to engage AND stationed at EACH gate — an undefended gate is a free corridor for the intruder to reach the nearest
|
| 36 |
+
asset.
|
| 37 |
+
benchmark_anchor:
|
| 38 |
+
- ERQA spatial commit (read terrain → assign defenders to chokepoints)
|
| 39 |
+
- MicroRTS chokepoint defense
|
| 40 |
+
- 'military doctrine: defense at obstacle-channelized terrain'
|
| 41 |
+
author: openra-bench
|
| 42 |
+
base_map: rush-hour-arena
|
| 43 |
+
starting_cash: 1000
|
| 44 |
+
base:
|
| 45 |
+
agent:
|
| 46 |
+
faction: allies
|
| 47 |
+
cash: 1000
|
| 48 |
+
enemy:
|
| 49 |
+
faction: soviet
|
| 50 |
+
cash: 0
|
| 51 |
+
tools:
|
| 52 |
+
- observe
|
| 53 |
+
- move_units
|
| 54 |
+
- attack_unit
|
| 55 |
+
- attack_move
|
| 56 |
+
- stop
|
| 57 |
+
- set_stance
|
| 58 |
+
spawn_mcvs: false
|
| 59 |
+
planning: true
|
| 60 |
+
termination:
|
| 61 |
+
max_ticks: 6000
|
| 62 |
+
actors: []
|
| 63 |
+
levels:
|
| 64 |
+
easy:
|
| 65 |
+
description: A water band cuts the map east-to-west with a single bridge at the centre. Six riflemen attack from the north.
|
| 66 |
+
Your defenders guard your base on HoldFire (stance 0) — they will NOT engage unless you flip stance and move them to
|
| 67 |
+
the bridge. Win = kill ≥4 attackers AND keep your fact alive, before turn 30.
|
| 68 |
+
starting_cash: 1000
|
| 69 |
+
overrides:
|
| 70 |
+
actors:
|
| 71 |
+
- &id001
|
| 72 |
+
type: fact
|
| 73 |
+
owner: agent
|
| 74 |
+
position:
|
| 75 |
+
- 10
|
| 76 |
+
- 33
|
| 77 |
+
- &id002
|
| 78 |
+
type: powr
|
| 79 |
+
owner: agent
|
| 80 |
+
position:
|
| 81 |
+
- 10
|
| 82 |
+
- 35
|
| 83 |
+
- type: e1
|
| 84 |
+
owner: agent
|
| 85 |
+
position:
|
| 86 |
+
- 58
|
| 87 |
+
- 30
|
| 88 |
+
stance: 0
|
| 89 |
+
- type: e1
|
| 90 |
+
owner: agent
|
| 91 |
+
position:
|
| 92 |
+
- 59
|
| 93 |
+
- 30
|
| 94 |
+
stance: 0
|
| 95 |
+
- type: e1
|
| 96 |
+
owner: agent
|
| 97 |
+
position:
|
| 98 |
+
- 60
|
| 99 |
+
- 30
|
| 100 |
+
stance: 0
|
| 101 |
+
- type: e1
|
| 102 |
+
owner: agent
|
| 103 |
+
position:
|
| 104 |
+
- 61
|
| 105 |
+
- 30
|
| 106 |
+
stance: 0
|
| 107 |
+
- type: e1
|
| 108 |
+
owner: agent
|
| 109 |
+
position:
|
| 110 |
+
- 62
|
| 111 |
+
- 30
|
| 112 |
+
stance: 0
|
| 113 |
+
- type: e1
|
| 114 |
+
owner: agent
|
| 115 |
+
position:
|
| 116 |
+
- 63
|
| 117 |
+
- 30
|
| 118 |
+
stance: 0
|
| 119 |
+
- type: e1
|
| 120 |
+
owner: enemy
|
| 121 |
+
position:
|
| 122 |
+
- 58
|
| 123 |
+
- 4
|
| 124 |
+
stance: 3
|
| 125 |
+
- type: e1
|
| 126 |
+
owner: enemy
|
| 127 |
+
position:
|
| 128 |
+
- 59
|
| 129 |
+
- 4
|
| 130 |
+
stance: 3
|
| 131 |
+
- type: e1
|
| 132 |
+
owner: enemy
|
| 133 |
+
position:
|
| 134 |
+
- 60
|
| 135 |
+
- 4
|
| 136 |
+
stance: 3
|
| 137 |
+
- type: e1
|
| 138 |
+
owner: enemy
|
| 139 |
+
position:
|
| 140 |
+
- 61
|
| 141 |
+
- 4
|
| 142 |
+
stance: 3
|
| 143 |
+
- type: e1
|
| 144 |
+
owner: enemy
|
| 145 |
+
position:
|
| 146 |
+
- 62
|
| 147 |
+
- 4
|
| 148 |
+
stance: 3
|
| 149 |
+
- type: e1
|
| 150 |
+
owner: enemy
|
| 151 |
+
position:
|
| 152 |
+
- 63
|
| 153 |
+
- 4
|
| 154 |
+
stance: 3
|
| 155 |
+
- type: fact
|
| 156 |
+
owner: enemy
|
| 157 |
+
position:
|
| 158 |
+
- 120
|
| 159 |
+
- 4
|
| 160 |
+
water_cells:
|
| 161 |
+
- [0, 18]
|
| 162 |
+
- [1, 18]
|
| 163 |
+
- [2, 18]
|
| 164 |
+
- [3, 18]
|
| 165 |
+
- [4, 18]
|
| 166 |
+
- [5, 18]
|
| 167 |
+
- [6, 18]
|
| 168 |
+
- [7, 18]
|
| 169 |
+
- [8, 18]
|
| 170 |
+
- [9, 18]
|
| 171 |
+
- [10, 18]
|
| 172 |
+
- [11, 18]
|
| 173 |
+
- [12, 18]
|
| 174 |
+
- [13, 18]
|
| 175 |
+
- [14, 18]
|
| 176 |
+
- [15, 18]
|
| 177 |
+
- [16, 18]
|
| 178 |
+
- [17, 18]
|
| 179 |
+
- [18, 18]
|
| 180 |
+
- [19, 18]
|
| 181 |
+
- [20, 18]
|
| 182 |
+
- [21, 18]
|
| 183 |
+
- [22, 18]
|
| 184 |
+
- [23, 18]
|
| 185 |
+
- [24, 18]
|
| 186 |
+
- [25, 18]
|
| 187 |
+
- [26, 18]
|
| 188 |
+
- [27, 18]
|
| 189 |
+
- [28, 18]
|
| 190 |
+
- [29, 18]
|
| 191 |
+
- [30, 18]
|
| 192 |
+
- [31, 18]
|
| 193 |
+
- [32, 18]
|
| 194 |
+
- [33, 18]
|
| 195 |
+
- [34, 18]
|
| 196 |
+
- [35, 18]
|
| 197 |
+
- [36, 18]
|
| 198 |
+
- [37, 18]
|
| 199 |
+
- [38, 18]
|
| 200 |
+
- [39, 18]
|
| 201 |
+
- [40, 18]
|
| 202 |
+
- [41, 18]
|
| 203 |
+
- [42, 18]
|
| 204 |
+
- [43, 18]
|
| 205 |
+
- [44, 18]
|
| 206 |
+
- [45, 18]
|
| 207 |
+
- [46, 18]
|
| 208 |
+
- [47, 18]
|
| 209 |
+
- [48, 18]
|
| 210 |
+
- [49, 18]
|
| 211 |
+
- [50, 18]
|
| 212 |
+
- [51, 18]
|
| 213 |
+
- [52, 18]
|
| 214 |
+
- [53, 18]
|
| 215 |
+
- [54, 18]
|
| 216 |
+
- [55, 18]
|
| 217 |
+
- [56, 18]
|
| 218 |
+
- [57, 18]
|
| 219 |
+
- [58, 18]
|
| 220 |
+
- [59, 18]
|
| 221 |
+
- [64, 18]
|
| 222 |
+
- [65, 18]
|
| 223 |
+
- [66, 18]
|
| 224 |
+
- [67, 18]
|
| 225 |
+
- [68, 18]
|
| 226 |
+
- [69, 18]
|
| 227 |
+
- [70, 18]
|
| 228 |
+
- [71, 18]
|
| 229 |
+
- [72, 18]
|
| 230 |
+
- [73, 18]
|
| 231 |
+
- [74, 18]
|
| 232 |
+
- [75, 18]
|
| 233 |
+
- [76, 18]
|
| 234 |
+
- [77, 18]
|
| 235 |
+
- [78, 18]
|
| 236 |
+
- [79, 18]
|
| 237 |
+
- [80, 18]
|
| 238 |
+
- [81, 18]
|
| 239 |
+
- [82, 18]
|
| 240 |
+
- [83, 18]
|
| 241 |
+
- [84, 18]
|
| 242 |
+
- [85, 18]
|
| 243 |
+
- [86, 18]
|
| 244 |
+
- [87, 18]
|
| 245 |
+
- [88, 18]
|
| 246 |
+
- [89, 18]
|
| 247 |
+
- [90, 18]
|
| 248 |
+
- [91, 18]
|
| 249 |
+
- [92, 18]
|
| 250 |
+
- [93, 18]
|
| 251 |
+
- [94, 18]
|
| 252 |
+
- [95, 18]
|
| 253 |
+
- [96, 18]
|
| 254 |
+
- [97, 18]
|
| 255 |
+
- [98, 18]
|
| 256 |
+
- [99, 18]
|
| 257 |
+
- [100, 18]
|
| 258 |
+
- [101, 18]
|
| 259 |
+
- [102, 18]
|
| 260 |
+
- [103, 18]
|
| 261 |
+
- [104, 18]
|
| 262 |
+
- [105, 18]
|
| 263 |
+
- [106, 18]
|
| 264 |
+
- [107, 18]
|
| 265 |
+
- [108, 18]
|
| 266 |
+
- [109, 18]
|
| 267 |
+
- [110, 18]
|
| 268 |
+
- [111, 18]
|
| 269 |
+
- [112, 18]
|
| 270 |
+
- [113, 18]
|
| 271 |
+
- [114, 18]
|
| 272 |
+
- [115, 18]
|
| 273 |
+
- [116, 18]
|
| 274 |
+
- [117, 18]
|
| 275 |
+
- [118, 18]
|
| 276 |
+
- [119, 18]
|
| 277 |
+
- [120, 18]
|
| 278 |
+
- [121, 18]
|
| 279 |
+
- [122, 18]
|
| 280 |
+
- [123, 18]
|
| 281 |
+
- [124, 18]
|
| 282 |
+
- [125, 18]
|
| 283 |
+
- [126, 18]
|
| 284 |
+
- [127, 18]
|
| 285 |
+
- [0, 19]
|
| 286 |
+
- [1, 19]
|
| 287 |
+
- [2, 19]
|
| 288 |
+
- [3, 19]
|
| 289 |
+
- [4, 19]
|
| 290 |
+
- [5, 19]
|
| 291 |
+
- [6, 19]
|
| 292 |
+
- [7, 19]
|
| 293 |
+
- [8, 19]
|
| 294 |
+
- [9, 19]
|
| 295 |
+
- [10, 19]
|
| 296 |
+
- [11, 19]
|
| 297 |
+
- [12, 19]
|
| 298 |
+
- [13, 19]
|
| 299 |
+
- [14, 19]
|
| 300 |
+
- [15, 19]
|
| 301 |
+
- [16, 19]
|
| 302 |
+
- [17, 19]
|
| 303 |
+
- [18, 19]
|
| 304 |
+
- [19, 19]
|
| 305 |
+
- [20, 19]
|
| 306 |
+
- [21, 19]
|
| 307 |
+
- [22, 19]
|
| 308 |
+
- [23, 19]
|
| 309 |
+
- [24, 19]
|
| 310 |
+
- [25, 19]
|
| 311 |
+
- [26, 19]
|
| 312 |
+
- [27, 19]
|
| 313 |
+
- [28, 19]
|
| 314 |
+
- [29, 19]
|
| 315 |
+
- [30, 19]
|
| 316 |
+
- [31, 19]
|
| 317 |
+
- [32, 19]
|
| 318 |
+
- [33, 19]
|
| 319 |
+
- [34, 19]
|
| 320 |
+
- [35, 19]
|
| 321 |
+
- [36, 19]
|
| 322 |
+
- [37, 19]
|
| 323 |
+
- [38, 19]
|
| 324 |
+
- [39, 19]
|
| 325 |
+
- [40, 19]
|
| 326 |
+
- [41, 19]
|
| 327 |
+
- [42, 19]
|
| 328 |
+
- [43, 19]
|
| 329 |
+
- [44, 19]
|
| 330 |
+
- [45, 19]
|
| 331 |
+
- [46, 19]
|
| 332 |
+
- [47, 19]
|
| 333 |
+
- [48, 19]
|
| 334 |
+
- [49, 19]
|
| 335 |
+
- [50, 19]
|
| 336 |
+
- [51, 19]
|
| 337 |
+
- [52, 19]
|
| 338 |
+
- [53, 19]
|
| 339 |
+
- [54, 19]
|
| 340 |
+
- [55, 19]
|
| 341 |
+
- [56, 19]
|
| 342 |
+
- [57, 19]
|
| 343 |
+
- [58, 19]
|
| 344 |
+
- [59, 19]
|
| 345 |
+
- [64, 19]
|
| 346 |
+
- [65, 19]
|
| 347 |
+
- [66, 19]
|
| 348 |
+
- [67, 19]
|
| 349 |
+
- [68, 19]
|
| 350 |
+
- [69, 19]
|
| 351 |
+
- [70, 19]
|
| 352 |
+
- [71, 19]
|
| 353 |
+
- [72, 19]
|
| 354 |
+
- [73, 19]
|
| 355 |
+
- [74, 19]
|
| 356 |
+
- [75, 19]
|
| 357 |
+
- [76, 19]
|
| 358 |
+
- [77, 19]
|
| 359 |
+
- [78, 19]
|
| 360 |
+
- [79, 19]
|
| 361 |
+
- [80, 19]
|
| 362 |
+
- [81, 19]
|
| 363 |
+
- [82, 19]
|
| 364 |
+
- [83, 19]
|
| 365 |
+
- [84, 19]
|
| 366 |
+
- [85, 19]
|
| 367 |
+
- [86, 19]
|
| 368 |
+
- [87, 19]
|
| 369 |
+
- [88, 19]
|
| 370 |
+
- [89, 19]
|
| 371 |
+
- [90, 19]
|
| 372 |
+
- [91, 19]
|
| 373 |
+
- [92, 19]
|
| 374 |
+
- [93, 19]
|
| 375 |
+
- [94, 19]
|
| 376 |
+
- [95, 19]
|
| 377 |
+
- [96, 19]
|
| 378 |
+
- [97, 19]
|
| 379 |
+
- [98, 19]
|
| 380 |
+
- [99, 19]
|
| 381 |
+
- [100, 19]
|
| 382 |
+
- [101, 19]
|
| 383 |
+
- [102, 19]
|
| 384 |
+
- [103, 19]
|
| 385 |
+
- [104, 19]
|
| 386 |
+
- [105, 19]
|
| 387 |
+
- [106, 19]
|
| 388 |
+
- [107, 19]
|
| 389 |
+
- [108, 19]
|
| 390 |
+
- [109, 19]
|
| 391 |
+
- [110, 19]
|
| 392 |
+
- [111, 19]
|
| 393 |
+
- [112, 19]
|
| 394 |
+
- [113, 19]
|
| 395 |
+
- [114, 19]
|
| 396 |
+
- [115, 19]
|
| 397 |
+
- [116, 19]
|
| 398 |
+
- [117, 19]
|
| 399 |
+
- [118, 19]
|
| 400 |
+
- [119, 19]
|
| 401 |
+
- [120, 19]
|
| 402 |
+
- [121, 19]
|
| 403 |
+
- [122, 19]
|
| 404 |
+
- [123, 19]
|
| 405 |
+
- [124, 19]
|
| 406 |
+
- [125, 19]
|
| 407 |
+
- [126, 19]
|
| 408 |
+
- [127, 19]
|
| 409 |
+
- [0, 20]
|
| 410 |
+
- [1, 20]
|
| 411 |
+
- [2, 20]
|
| 412 |
+
- [3, 20]
|
| 413 |
+
- [4, 20]
|
| 414 |
+
- [5, 20]
|
| 415 |
+
- [6, 20]
|
| 416 |
+
- [7, 20]
|
| 417 |
+
- [8, 20]
|
| 418 |
+
- [9, 20]
|
| 419 |
+
- [10, 20]
|
| 420 |
+
- [11, 20]
|
| 421 |
+
- [12, 20]
|
| 422 |
+
- [13, 20]
|
| 423 |
+
- [14, 20]
|
| 424 |
+
- [15, 20]
|
| 425 |
+
- [16, 20]
|
| 426 |
+
- [17, 20]
|
| 427 |
+
- [18, 20]
|
| 428 |
+
- [19, 20]
|
| 429 |
+
- [20, 20]
|
| 430 |
+
- [21, 20]
|
| 431 |
+
- [22, 20]
|
| 432 |
+
- [23, 20]
|
| 433 |
+
- [24, 20]
|
| 434 |
+
- [25, 20]
|
| 435 |
+
- [26, 20]
|
| 436 |
+
- [27, 20]
|
| 437 |
+
- [28, 20]
|
| 438 |
+
- [29, 20]
|
| 439 |
+
- [30, 20]
|
| 440 |
+
- [31, 20]
|
| 441 |
+
- [32, 20]
|
| 442 |
+
- [33, 20]
|
| 443 |
+
- [34, 20]
|
| 444 |
+
- [35, 20]
|
| 445 |
+
- [36, 20]
|
| 446 |
+
- [37, 20]
|
| 447 |
+
- [38, 20]
|
| 448 |
+
- [39, 20]
|
| 449 |
+
- [40, 20]
|
| 450 |
+
- [41, 20]
|
| 451 |
+
- [42, 20]
|
| 452 |
+
- [43, 20]
|
| 453 |
+
- [44, 20]
|
| 454 |
+
- [45, 20]
|
| 455 |
+
- [46, 20]
|
| 456 |
+
- [47, 20]
|
| 457 |
+
- [48, 20]
|
| 458 |
+
- [49, 20]
|
| 459 |
+
- [50, 20]
|
| 460 |
+
- [51, 20]
|
| 461 |
+
- [52, 20]
|
| 462 |
+
- [53, 20]
|
| 463 |
+
- [54, 20]
|
| 464 |
+
- [55, 20]
|
| 465 |
+
- [56, 20]
|
| 466 |
+
- [57, 20]
|
| 467 |
+
- [58, 20]
|
| 468 |
+
- [59, 20]
|
| 469 |
+
- [64, 20]
|
| 470 |
+
- [65, 20]
|
| 471 |
+
- [66, 20]
|
| 472 |
+
- [67, 20]
|
| 473 |
+
- [68, 20]
|
| 474 |
+
- [69, 20]
|
| 475 |
+
- [70, 20]
|
| 476 |
+
- [71, 20]
|
| 477 |
+
- [72, 20]
|
| 478 |
+
- [73, 20]
|
| 479 |
+
- [74, 20]
|
| 480 |
+
- [75, 20]
|
| 481 |
+
- [76, 20]
|
| 482 |
+
- [77, 20]
|
| 483 |
+
- [78, 20]
|
| 484 |
+
- [79, 20]
|
| 485 |
+
- [80, 20]
|
| 486 |
+
- [81, 20]
|
| 487 |
+
- [82, 20]
|
| 488 |
+
- [83, 20]
|
| 489 |
+
- [84, 20]
|
| 490 |
+
- [85, 20]
|
| 491 |
+
- [86, 20]
|
| 492 |
+
- [87, 20]
|
| 493 |
+
- [88, 20]
|
| 494 |
+
- [89, 20]
|
| 495 |
+
- [90, 20]
|
| 496 |
+
- [91, 20]
|
| 497 |
+
- [92, 20]
|
| 498 |
+
- [93, 20]
|
| 499 |
+
- [94, 20]
|
| 500 |
+
- [95, 20]
|
| 501 |
+
- [96, 20]
|
| 502 |
+
- [97, 20]
|
| 503 |
+
- [98, 20]
|
| 504 |
+
- [99, 20]
|
| 505 |
+
- [100, 20]
|
| 506 |
+
- [101, 20]
|
| 507 |
+
- [102, 20]
|
| 508 |
+
- [103, 20]
|
| 509 |
+
- [104, 20]
|
| 510 |
+
- [105, 20]
|
| 511 |
+
- [106, 20]
|
| 512 |
+
- [107, 20]
|
| 513 |
+
- [108, 20]
|
| 514 |
+
- [109, 20]
|
| 515 |
+
- [110, 20]
|
| 516 |
+
- [111, 20]
|
| 517 |
+
- [112, 20]
|
| 518 |
+
- [113, 20]
|
| 519 |
+
- [114, 20]
|
| 520 |
+
- [115, 20]
|
| 521 |
+
- [116, 20]
|
| 522 |
+
- [117, 20]
|
| 523 |
+
- [118, 20]
|
| 524 |
+
- [119, 20]
|
| 525 |
+
- [120, 20]
|
| 526 |
+
- [121, 20]
|
| 527 |
+
- [122, 20]
|
| 528 |
+
- [123, 20]
|
| 529 |
+
- [124, 20]
|
| 530 |
+
- [125, 20]
|
| 531 |
+
- [126, 20]
|
| 532 |
+
- [127, 20]
|
| 533 |
+
- [0, 21]
|
| 534 |
+
- [1, 21]
|
| 535 |
+
- [2, 21]
|
| 536 |
+
- [3, 21]
|
| 537 |
+
- [4, 21]
|
| 538 |
+
- [5, 21]
|
| 539 |
+
- [6, 21]
|
| 540 |
+
- [7, 21]
|
| 541 |
+
- [8, 21]
|
| 542 |
+
- [9, 21]
|
| 543 |
+
- [10, 21]
|
| 544 |
+
- [11, 21]
|
| 545 |
+
- [12, 21]
|
| 546 |
+
- [13, 21]
|
| 547 |
+
- [14, 21]
|
| 548 |
+
- [15, 21]
|
| 549 |
+
- [16, 21]
|
| 550 |
+
- [17, 21]
|
| 551 |
+
- [18, 21]
|
| 552 |
+
- [19, 21]
|
| 553 |
+
- [20, 21]
|
| 554 |
+
- [21, 21]
|
| 555 |
+
- [22, 21]
|
| 556 |
+
- [23, 21]
|
| 557 |
+
- [24, 21]
|
| 558 |
+
- [25, 21]
|
| 559 |
+
- [26, 21]
|
| 560 |
+
- [27, 21]
|
| 561 |
+
- [28, 21]
|
| 562 |
+
- [29, 21]
|
| 563 |
+
- [30, 21]
|
| 564 |
+
- [31, 21]
|
| 565 |
+
- [32, 21]
|
| 566 |
+
- [33, 21]
|
| 567 |
+
- [34, 21]
|
| 568 |
+
- [35, 21]
|
| 569 |
+
- [36, 21]
|
| 570 |
+
- [37, 21]
|
| 571 |
+
- [38, 21]
|
| 572 |
+
- [39, 21]
|
| 573 |
+
- [40, 21]
|
| 574 |
+
- [41, 21]
|
| 575 |
+
- [42, 21]
|
| 576 |
+
- [43, 21]
|
| 577 |
+
- [44, 21]
|
| 578 |
+
- [45, 21]
|
| 579 |
+
- [46, 21]
|
| 580 |
+
- [47, 21]
|
| 581 |
+
- [48, 21]
|
| 582 |
+
- [49, 21]
|
| 583 |
+
- [50, 21]
|
| 584 |
+
- [51, 21]
|
| 585 |
+
- [52, 21]
|
| 586 |
+
- [53, 21]
|
| 587 |
+
- [54, 21]
|
| 588 |
+
- [55, 21]
|
| 589 |
+
- [56, 21]
|
| 590 |
+
- [57, 21]
|
| 591 |
+
- [58, 21]
|
| 592 |
+
- [59, 21]
|
| 593 |
+
- [64, 21]
|
| 594 |
+
- [65, 21]
|
| 595 |
+
- [66, 21]
|
| 596 |
+
- [67, 21]
|
| 597 |
+
- [68, 21]
|
| 598 |
+
- [69, 21]
|
| 599 |
+
- [70, 21]
|
| 600 |
+
- [71, 21]
|
| 601 |
+
- [72, 21]
|
| 602 |
+
- [73, 21]
|
| 603 |
+
- [74, 21]
|
| 604 |
+
- [75, 21]
|
| 605 |
+
- [76, 21]
|
| 606 |
+
- [77, 21]
|
| 607 |
+
- [78, 21]
|
| 608 |
+
- [79, 21]
|
| 609 |
+
- [80, 21]
|
| 610 |
+
- [81, 21]
|
| 611 |
+
- [82, 21]
|
| 612 |
+
- [83, 21]
|
| 613 |
+
- [84, 21]
|
| 614 |
+
- [85, 21]
|
| 615 |
+
- [86, 21]
|
| 616 |
+
- [87, 21]
|
| 617 |
+
- [88, 21]
|
| 618 |
+
- [89, 21]
|
| 619 |
+
- [90, 21]
|
| 620 |
+
- [91, 21]
|
| 621 |
+
- [92, 21]
|
| 622 |
+
- [93, 21]
|
| 623 |
+
- [94, 21]
|
| 624 |
+
- [95, 21]
|
| 625 |
+
- [96, 21]
|
| 626 |
+
- [97, 21]
|
| 627 |
+
- [98, 21]
|
| 628 |
+
- [99, 21]
|
| 629 |
+
- [100, 21]
|
| 630 |
+
- [101, 21]
|
| 631 |
+
- [102, 21]
|
| 632 |
+
- [103, 21]
|
| 633 |
+
- [104, 21]
|
| 634 |
+
- [105, 21]
|
| 635 |
+
- [106, 21]
|
| 636 |
+
- [107, 21]
|
| 637 |
+
- [108, 21]
|
| 638 |
+
- [109, 21]
|
| 639 |
+
- [110, 21]
|
| 640 |
+
- [111, 21]
|
| 641 |
+
- [112, 21]
|
| 642 |
+
- [113, 21]
|
| 643 |
+
- [114, 21]
|
| 644 |
+
- [115, 21]
|
| 645 |
+
- [116, 21]
|
| 646 |
+
- [117, 21]
|
| 647 |
+
- [118, 21]
|
| 648 |
+
- [119, 21]
|
| 649 |
+
- [120, 21]
|
| 650 |
+
- [121, 21]
|
| 651 |
+
- [122, 21]
|
| 652 |
+
- [123, 21]
|
| 653 |
+
- [124, 21]
|
| 654 |
+
- [125, 21]
|
| 655 |
+
- [126, 21]
|
| 656 |
+
- [127, 21]
|
| 657 |
+
win_condition:
|
| 658 |
+
all_of:
|
| 659 |
+
- units_killed_gte: 4
|
| 660 |
+
- has_building: fact
|
| 661 |
+
- within_ticks: 2700
|
| 662 |
+
fail_condition:
|
| 663 |
+
any_of:
|
| 664 |
+
- after_ticks: 2701
|
| 665 |
+
- not:
|
| 666 |
+
has_building: fact
|
| 667 |
+
max_turns: 35
|
| 668 |
+
medium:
|
| 669 |
+
description: Two bridges (west-of-centre and east-of-centre) cross the water. Each bridge has a refinery (proc) directly
|
| 670 |
+
behind it that the attackers will destroy if unopposed. Six riflemen attack through EACH bridge. Defenders are on HoldFire
|
| 671 |
+
(stance 0) at the centre; you must split + flip stance + intercept at both bridges. Win = kill ≥8 attackers AND keep
|
| 672 |
+
BOTH procs alive, before turn 35.
|
| 673 |
+
starting_cash: 1000
|
| 674 |
+
overrides:
|
| 675 |
+
actors:
|
| 676 |
+
- *id001
|
| 677 |
+
- *id002
|
| 678 |
+
- type: proc
|
| 679 |
+
owner: agent
|
| 680 |
+
position:
|
| 681 |
+
- 40
|
| 682 |
+
- 26
|
| 683 |
+
- type: proc
|
| 684 |
+
owner: agent
|
| 685 |
+
position:
|
| 686 |
+
- 82
|
| 687 |
+
- 26
|
| 688 |
+
- type: e1
|
| 689 |
+
owner: agent
|
| 690 |
+
position:
|
| 691 |
+
- 59
|
| 692 |
+
- 30
|
| 693 |
+
stance: 0
|
| 694 |
+
- type: e1
|
| 695 |
+
owner: agent
|
| 696 |
+
position:
|
| 697 |
+
- 60
|
| 698 |
+
- 30
|
| 699 |
+
stance: 0
|
| 700 |
+
- type: e1
|
| 701 |
+
owner: agent
|
| 702 |
+
position:
|
| 703 |
+
- 61
|
| 704 |
+
- 30
|
| 705 |
+
stance: 0
|
| 706 |
+
- type: e1
|
| 707 |
+
owner: agent
|
| 708 |
+
position:
|
| 709 |
+
- 62
|
| 710 |
+
- 30
|
| 711 |
+
stance: 0
|
| 712 |
+
- type: e1
|
| 713 |
+
owner: agent
|
| 714 |
+
position:
|
| 715 |
+
- 63
|
| 716 |
+
- 30
|
| 717 |
+
stance: 0
|
| 718 |
+
- type: e1
|
| 719 |
+
owner: agent
|
| 720 |
+
position:
|
| 721 |
+
- 64
|
| 722 |
+
- 30
|
| 723 |
+
stance: 0
|
| 724 |
+
- type: e1
|
| 725 |
+
owner: agent
|
| 726 |
+
position:
|
| 727 |
+
- 65
|
| 728 |
+
- 30
|
| 729 |
+
stance: 0
|
| 730 |
+
- type: e1
|
| 731 |
+
owner: agent
|
| 732 |
+
position:
|
| 733 |
+
- 59
|
| 734 |
+
- 31
|
| 735 |
+
stance: 0
|
| 736 |
+
- type: e1
|
| 737 |
+
owner: agent
|
| 738 |
+
position:
|
| 739 |
+
- 60
|
| 740 |
+
- 31
|
| 741 |
+
stance: 0
|
| 742 |
+
- type: e1
|
| 743 |
+
owner: agent
|
| 744 |
+
position:
|
| 745 |
+
- 61
|
| 746 |
+
- 31
|
| 747 |
+
stance: 0
|
| 748 |
+
- type: e1
|
| 749 |
+
owner: agent
|
| 750 |
+
position:
|
| 751 |
+
- 62
|
| 752 |
+
- 31
|
| 753 |
+
stance: 0
|
| 754 |
+
- type: e1
|
| 755 |
+
owner: agent
|
| 756 |
+
position:
|
| 757 |
+
- 63
|
| 758 |
+
- 31
|
| 759 |
+
stance: 0
|
| 760 |
+
- type: e1
|
| 761 |
+
owner: enemy
|
| 762 |
+
position:
|
| 763 |
+
- 38
|
| 764 |
+
- 4
|
| 765 |
+
stance: 3
|
| 766 |
+
- type: e1
|
| 767 |
+
owner: enemy
|
| 768 |
+
position:
|
| 769 |
+
- 39
|
| 770 |
+
- 4
|
| 771 |
+
stance: 3
|
| 772 |
+
- type: e1
|
| 773 |
+
owner: enemy
|
| 774 |
+
position:
|
| 775 |
+
- 40
|
| 776 |
+
- 4
|
| 777 |
+
stance: 3
|
| 778 |
+
- type: e1
|
| 779 |
+
owner: enemy
|
| 780 |
+
position:
|
| 781 |
+
- 41
|
| 782 |
+
- 4
|
| 783 |
+
stance: 3
|
| 784 |
+
- type: e1
|
| 785 |
+
owner: enemy
|
| 786 |
+
position:
|
| 787 |
+
- 42
|
| 788 |
+
- 4
|
| 789 |
+
stance: 3
|
| 790 |
+
- type: e1
|
| 791 |
+
owner: enemy
|
| 792 |
+
position:
|
| 793 |
+
- 43
|
| 794 |
+
- 4
|
| 795 |
+
stance: 3
|
| 796 |
+
- type: e1
|
| 797 |
+
owner: enemy
|
| 798 |
+
position:
|
| 799 |
+
- 80
|
| 800 |
+
- 4
|
| 801 |
+
stance: 3
|
| 802 |
+
- type: e1
|
| 803 |
+
owner: enemy
|
| 804 |
+
position:
|
| 805 |
+
- 81
|
| 806 |
+
- 4
|
| 807 |
+
stance: 3
|
| 808 |
+
- type: e1
|
| 809 |
+
owner: enemy
|
| 810 |
+
position:
|
| 811 |
+
- 82
|
| 812 |
+
- 4
|
| 813 |
+
stance: 3
|
| 814 |
+
- type: e1
|
| 815 |
+
owner: enemy
|
| 816 |
+
position:
|
| 817 |
+
- 83
|
| 818 |
+
- 4
|
| 819 |
+
stance: 3
|
| 820 |
+
- type: e1
|
| 821 |
+
owner: enemy
|
| 822 |
+
position:
|
| 823 |
+
- 84
|
| 824 |
+
- 4
|
| 825 |
+
stance: 3
|
| 826 |
+
- type: e1
|
| 827 |
+
owner: enemy
|
| 828 |
+
position:
|
| 829 |
+
- 85
|
| 830 |
+
- 4
|
| 831 |
+
stance: 3
|
| 832 |
+
- type: fact
|
| 833 |
+
owner: enemy
|
| 834 |
+
position:
|
| 835 |
+
- 120
|
| 836 |
+
- 4
|
| 837 |
+
water_cells:
|
| 838 |
+
- [0, 18]
|
| 839 |
+
- [1, 18]
|
| 840 |
+
- [2, 18]
|
| 841 |
+
- [3, 18]
|
| 842 |
+
- [4, 18]
|
| 843 |
+
- [5, 18]
|
| 844 |
+
- [6, 18]
|
| 845 |
+
- [7, 18]
|
| 846 |
+
- [8, 18]
|
| 847 |
+
- [9, 18]
|
| 848 |
+
- [10, 18]
|
| 849 |
+
- [11, 18]
|
| 850 |
+
- [12, 18]
|
| 851 |
+
- [13, 18]
|
| 852 |
+
- [14, 18]
|
| 853 |
+
- [15, 18]
|
| 854 |
+
- [16, 18]
|
| 855 |
+
- [17, 18]
|
| 856 |
+
- [18, 18]
|
| 857 |
+
- [19, 18]
|
| 858 |
+
- [20, 18]
|
| 859 |
+
- [21, 18]
|
| 860 |
+
- [22, 18]
|
| 861 |
+
- [23, 18]
|
| 862 |
+
- [24, 18]
|
| 863 |
+
- [25, 18]
|
| 864 |
+
- [26, 18]
|
| 865 |
+
- [27, 18]
|
| 866 |
+
- [28, 18]
|
| 867 |
+
- [29, 18]
|
| 868 |
+
- [30, 18]
|
| 869 |
+
- [31, 18]
|
| 870 |
+
- [32, 18]
|
| 871 |
+
- [33, 18]
|
| 872 |
+
- [34, 18]
|
| 873 |
+
- [35, 18]
|
| 874 |
+
- [36, 18]
|
| 875 |
+
- [37, 18]
|
| 876 |
+
- [38, 18]
|
| 877 |
+
- [39, 18]
|
| 878 |
+
- [44, 18]
|
| 879 |
+
- [45, 18]
|
| 880 |
+
- [46, 18]
|
| 881 |
+
- [47, 18]
|
| 882 |
+
- [48, 18]
|
| 883 |
+
- [49, 18]
|
| 884 |
+
- [50, 18]
|
| 885 |
+
- [51, 18]
|
| 886 |
+
- [52, 18]
|
| 887 |
+
- [53, 18]
|
| 888 |
+
- [54, 18]
|
| 889 |
+
- [55, 18]
|
| 890 |
+
- [56, 18]
|
| 891 |
+
- [57, 18]
|
| 892 |
+
- [58, 18]
|
| 893 |
+
- [59, 18]
|
| 894 |
+
- [60, 18]
|
| 895 |
+
- [61, 18]
|
| 896 |
+
- [62, 18]
|
| 897 |
+
- [63, 18]
|
| 898 |
+
- [64, 18]
|
| 899 |
+
- [65, 18]
|
| 900 |
+
- [66, 18]
|
| 901 |
+
- [67, 18]
|
| 902 |
+
- [68, 18]
|
| 903 |
+
- [69, 18]
|
| 904 |
+
- [70, 18]
|
| 905 |
+
- [71, 18]
|
| 906 |
+
- [72, 18]
|
| 907 |
+
- [73, 18]
|
| 908 |
+
- [74, 18]
|
| 909 |
+
- [75, 18]
|
| 910 |
+
- [76, 18]
|
| 911 |
+
- [77, 18]
|
| 912 |
+
- [78, 18]
|
| 913 |
+
- [79, 18]
|
| 914 |
+
- [80, 18]
|
| 915 |
+
- [81, 18]
|
| 916 |
+
- [86, 18]
|
| 917 |
+
- [87, 18]
|
| 918 |
+
- [88, 18]
|
| 919 |
+
- [89, 18]
|
| 920 |
+
- [90, 18]
|
| 921 |
+
- [91, 18]
|
| 922 |
+
- [92, 18]
|
| 923 |
+
- [93, 18]
|
| 924 |
+
- [94, 18]
|
| 925 |
+
- [95, 18]
|
| 926 |
+
- [96, 18]
|
| 927 |
+
- [97, 18]
|
| 928 |
+
- [98, 18]
|
| 929 |
+
- [99, 18]
|
| 930 |
+
- [100, 18]
|
| 931 |
+
- [101, 18]
|
| 932 |
+
- [102, 18]
|
| 933 |
+
- [103, 18]
|
| 934 |
+
- [104, 18]
|
| 935 |
+
- [105, 18]
|
| 936 |
+
- [106, 18]
|
| 937 |
+
- [107, 18]
|
| 938 |
+
- [108, 18]
|
| 939 |
+
- [109, 18]
|
| 940 |
+
- [110, 18]
|
| 941 |
+
- [111, 18]
|
| 942 |
+
- [112, 18]
|
| 943 |
+
- [113, 18]
|
| 944 |
+
- [114, 18]
|
| 945 |
+
- [115, 18]
|
| 946 |
+
- [116, 18]
|
| 947 |
+
- [117, 18]
|
| 948 |
+
- [118, 18]
|
| 949 |
+
- [119, 18]
|
| 950 |
+
- [120, 18]
|
| 951 |
+
- [121, 18]
|
| 952 |
+
- [122, 18]
|
| 953 |
+
- [123, 18]
|
| 954 |
+
- [124, 18]
|
| 955 |
+
- [125, 18]
|
| 956 |
+
- [126, 18]
|
| 957 |
+
- [127, 18]
|
| 958 |
+
- [0, 19]
|
| 959 |
+
- [1, 19]
|
| 960 |
+
- [2, 19]
|
| 961 |
+
- [3, 19]
|
| 962 |
+
- [4, 19]
|
| 963 |
+
- [5, 19]
|
| 964 |
+
- [6, 19]
|
| 965 |
+
- [7, 19]
|
| 966 |
+
- [8, 19]
|
| 967 |
+
- [9, 19]
|
| 968 |
+
- [10, 19]
|
| 969 |
+
- [11, 19]
|
| 970 |
+
- [12, 19]
|
| 971 |
+
- [13, 19]
|
| 972 |
+
- [14, 19]
|
| 973 |
+
- [15, 19]
|
| 974 |
+
- [16, 19]
|
| 975 |
+
- [17, 19]
|
| 976 |
+
- [18, 19]
|
| 977 |
+
- [19, 19]
|
| 978 |
+
- [20, 19]
|
| 979 |
+
- [21, 19]
|
| 980 |
+
- [22, 19]
|
| 981 |
+
- [23, 19]
|
| 982 |
+
- [24, 19]
|
| 983 |
+
- [25, 19]
|
| 984 |
+
- [26, 19]
|
| 985 |
+
- [27, 19]
|
| 986 |
+
- [28, 19]
|
| 987 |
+
- [29, 19]
|
| 988 |
+
- [30, 19]
|
| 989 |
+
- [31, 19]
|
| 990 |
+
- [32, 19]
|
| 991 |
+
- [33, 19]
|
| 992 |
+
- [34, 19]
|
| 993 |
+
- [35, 19]
|
| 994 |
+
- [36, 19]
|
| 995 |
+
- [37, 19]
|
| 996 |
+
- [38, 19]
|
| 997 |
+
- [39, 19]
|
| 998 |
+
- [44, 19]
|
| 999 |
+
- [45, 19]
|
| 1000 |
+
- [46, 19]
|
| 1001 |
+
- [47, 19]
|
| 1002 |
+
- [48, 19]
|
| 1003 |
+
- [49, 19]
|
| 1004 |
+
- [50, 19]
|
| 1005 |
+
- [51, 19]
|
| 1006 |
+
- [52, 19]
|
| 1007 |
+
- [53, 19]
|
| 1008 |
+
- [54, 19]
|
| 1009 |
+
- [55, 19]
|
| 1010 |
+
- [56, 19]
|
| 1011 |
+
- [57, 19]
|
| 1012 |
+
- [58, 19]
|
| 1013 |
+
- [59, 19]
|
| 1014 |
+
- [60, 19]
|
| 1015 |
+
- [61, 19]
|
| 1016 |
+
- [62, 19]
|
| 1017 |
+
- [63, 19]
|
| 1018 |
+
- [64, 19]
|
| 1019 |
+
- [65, 19]
|
| 1020 |
+
- [66, 19]
|
| 1021 |
+
- [67, 19]
|
| 1022 |
+
- [68, 19]
|
| 1023 |
+
- [69, 19]
|
| 1024 |
+
- [70, 19]
|
| 1025 |
+
- [71, 19]
|
| 1026 |
+
- [72, 19]
|
| 1027 |
+
- [73, 19]
|
| 1028 |
+
- [74, 19]
|
| 1029 |
+
- [75, 19]
|
| 1030 |
+
- [76, 19]
|
| 1031 |
+
- [77, 19]
|
| 1032 |
+
- [78, 19]
|
| 1033 |
+
- [79, 19]
|
| 1034 |
+
- [80, 19]
|
| 1035 |
+
- [81, 19]
|
| 1036 |
+
- [86, 19]
|
| 1037 |
+
- [87, 19]
|
| 1038 |
+
- [88, 19]
|
| 1039 |
+
- [89, 19]
|
| 1040 |
+
- [90, 19]
|
| 1041 |
+
- [91, 19]
|
| 1042 |
+
- [92, 19]
|
| 1043 |
+
- [93, 19]
|
| 1044 |
+
- [94, 19]
|
| 1045 |
+
- [95, 19]
|
| 1046 |
+
- [96, 19]
|
| 1047 |
+
- [97, 19]
|
| 1048 |
+
- [98, 19]
|
| 1049 |
+
- [99, 19]
|
| 1050 |
+
- [100, 19]
|
| 1051 |
+
- [101, 19]
|
| 1052 |
+
- [102, 19]
|
| 1053 |
+
- [103, 19]
|
| 1054 |
+
- [104, 19]
|
| 1055 |
+
- [105, 19]
|
| 1056 |
+
- [106, 19]
|
| 1057 |
+
- [107, 19]
|
| 1058 |
+
- [108, 19]
|
| 1059 |
+
- [109, 19]
|
| 1060 |
+
- [110, 19]
|
| 1061 |
+
- [111, 19]
|
| 1062 |
+
- [112, 19]
|
| 1063 |
+
- [113, 19]
|
| 1064 |
+
- [114, 19]
|
| 1065 |
+
- [115, 19]
|
| 1066 |
+
- [116, 19]
|
| 1067 |
+
- [117, 19]
|
| 1068 |
+
- [118, 19]
|
| 1069 |
+
- [119, 19]
|
| 1070 |
+
- [120, 19]
|
| 1071 |
+
- [121, 19]
|
| 1072 |
+
- [122, 19]
|
| 1073 |
+
- [123, 19]
|
| 1074 |
+
- [124, 19]
|
| 1075 |
+
- [125, 19]
|
| 1076 |
+
- [126, 19]
|
| 1077 |
+
- [127, 19]
|
| 1078 |
+
- [0, 20]
|
| 1079 |
+
- [1, 20]
|
| 1080 |
+
- [2, 20]
|
| 1081 |
+
- [3, 20]
|
| 1082 |
+
- [4, 20]
|
| 1083 |
+
- [5, 20]
|
| 1084 |
+
- [6, 20]
|
| 1085 |
+
- [7, 20]
|
| 1086 |
+
- [8, 20]
|
| 1087 |
+
- [9, 20]
|
| 1088 |
+
- [10, 20]
|
| 1089 |
+
- [11, 20]
|
| 1090 |
+
- [12, 20]
|
| 1091 |
+
- [13, 20]
|
| 1092 |
+
- [14, 20]
|
| 1093 |
+
- [15, 20]
|
| 1094 |
+
- [16, 20]
|
| 1095 |
+
- [17, 20]
|
| 1096 |
+
- [18, 20]
|
| 1097 |
+
- [19, 20]
|
| 1098 |
+
- [20, 20]
|
| 1099 |
+
- [21, 20]
|
| 1100 |
+
- [22, 20]
|
| 1101 |
+
- [23, 20]
|
| 1102 |
+
- [24, 20]
|
| 1103 |
+
- [25, 20]
|
| 1104 |
+
- [26, 20]
|
| 1105 |
+
- [27, 20]
|
| 1106 |
+
- [28, 20]
|
| 1107 |
+
- [29, 20]
|
| 1108 |
+
- [30, 20]
|
| 1109 |
+
- [31, 20]
|
| 1110 |
+
- [32, 20]
|
| 1111 |
+
- [33, 20]
|
| 1112 |
+
- [34, 20]
|
| 1113 |
+
- [35, 20]
|
| 1114 |
+
- [36, 20]
|
| 1115 |
+
- [37, 20]
|
| 1116 |
+
- [38, 20]
|
| 1117 |
+
- [39, 20]
|
| 1118 |
+
- [44, 20]
|
| 1119 |
+
- [45, 20]
|
| 1120 |
+
- [46, 20]
|
| 1121 |
+
- [47, 20]
|
| 1122 |
+
- [48, 20]
|
| 1123 |
+
- [49, 20]
|
| 1124 |
+
- [50, 20]
|
| 1125 |
+
- [51, 20]
|
| 1126 |
+
- [52, 20]
|
| 1127 |
+
- [53, 20]
|
| 1128 |
+
- [54, 20]
|
| 1129 |
+
- [55, 20]
|
| 1130 |
+
- [56, 20]
|
| 1131 |
+
- [57, 20]
|
| 1132 |
+
- [58, 20]
|
| 1133 |
+
- [59, 20]
|
| 1134 |
+
- [60, 20]
|
| 1135 |
+
- [61, 20]
|
| 1136 |
+
- [62, 20]
|
| 1137 |
+
- [63, 20]
|
| 1138 |
+
- [64, 20]
|
| 1139 |
+
- [65, 20]
|
| 1140 |
+
- [66, 20]
|
| 1141 |
+
- [67, 20]
|
| 1142 |
+
- [68, 20]
|
| 1143 |
+
- [69, 20]
|
| 1144 |
+
- [70, 20]
|
| 1145 |
+
- [71, 20]
|
| 1146 |
+
- [72, 20]
|
| 1147 |
+
- [73, 20]
|
| 1148 |
+
- [74, 20]
|
| 1149 |
+
- [75, 20]
|
| 1150 |
+
- [76, 20]
|
| 1151 |
+
- [77, 20]
|
| 1152 |
+
- [78, 20]
|
| 1153 |
+
- [79, 20]
|
| 1154 |
+
- [80, 20]
|
| 1155 |
+
- [81, 20]
|
| 1156 |
+
- [86, 20]
|
| 1157 |
+
- [87, 20]
|
| 1158 |
+
- [88, 20]
|
| 1159 |
+
- [89, 20]
|
| 1160 |
+
- [90, 20]
|
| 1161 |
+
- [91, 20]
|
| 1162 |
+
- [92, 20]
|
| 1163 |
+
- [93, 20]
|
| 1164 |
+
- [94, 20]
|
| 1165 |
+
- [95, 20]
|
| 1166 |
+
- [96, 20]
|
| 1167 |
+
- [97, 20]
|
| 1168 |
+
- [98, 20]
|
| 1169 |
+
- [99, 20]
|
| 1170 |
+
- [100, 20]
|
| 1171 |
+
- [101, 20]
|
| 1172 |
+
- [102, 20]
|
| 1173 |
+
- [103, 20]
|
| 1174 |
+
- [104, 20]
|
| 1175 |
+
- [105, 20]
|
| 1176 |
+
- [106, 20]
|
| 1177 |
+
- [107, 20]
|
| 1178 |
+
- [108, 20]
|
| 1179 |
+
- [109, 20]
|
| 1180 |
+
- [110, 20]
|
| 1181 |
+
- [111, 20]
|
| 1182 |
+
- [112, 20]
|
| 1183 |
+
- [113, 20]
|
| 1184 |
+
- [114, 20]
|
| 1185 |
+
- [115, 20]
|
| 1186 |
+
- [116, 20]
|
| 1187 |
+
- [117, 20]
|
| 1188 |
+
- [118, 20]
|
| 1189 |
+
- [119, 20]
|
| 1190 |
+
- [120, 20]
|
| 1191 |
+
- [121, 20]
|
| 1192 |
+
- [122, 20]
|
| 1193 |
+
- [123, 20]
|
| 1194 |
+
- [124, 20]
|
| 1195 |
+
- [125, 20]
|
| 1196 |
+
- [126, 20]
|
| 1197 |
+
- [127, 20]
|
| 1198 |
+
- [0, 21]
|
| 1199 |
+
- [1, 21]
|
| 1200 |
+
- [2, 21]
|
| 1201 |
+
- [3, 21]
|
| 1202 |
+
- [4, 21]
|
| 1203 |
+
- [5, 21]
|
| 1204 |
+
- [6, 21]
|
| 1205 |
+
- [7, 21]
|
| 1206 |
+
- [8, 21]
|
| 1207 |
+
- [9, 21]
|
| 1208 |
+
- [10, 21]
|
| 1209 |
+
- [11, 21]
|
| 1210 |
+
- [12, 21]
|
| 1211 |
+
- [13, 21]
|
| 1212 |
+
- [14, 21]
|
| 1213 |
+
- [15, 21]
|
| 1214 |
+
- [16, 21]
|
| 1215 |
+
- [17, 21]
|
| 1216 |
+
- [18, 21]
|
| 1217 |
+
- [19, 21]
|
| 1218 |
+
- [20, 21]
|
| 1219 |
+
- [21, 21]
|
| 1220 |
+
- [22, 21]
|
| 1221 |
+
- [23, 21]
|
| 1222 |
+
- [24, 21]
|
| 1223 |
+
- [25, 21]
|
| 1224 |
+
- [26, 21]
|
| 1225 |
+
- [27, 21]
|
| 1226 |
+
- [28, 21]
|
| 1227 |
+
- [29, 21]
|
| 1228 |
+
- [30, 21]
|
| 1229 |
+
- [31, 21]
|
| 1230 |
+
- [32, 21]
|
| 1231 |
+
- [33, 21]
|
| 1232 |
+
- [34, 21]
|
| 1233 |
+
- [35, 21]
|
| 1234 |
+
- [36, 21]
|
| 1235 |
+
- [37, 21]
|
| 1236 |
+
- [38, 21]
|
| 1237 |
+
- [39, 21]
|
| 1238 |
+
- [44, 21]
|
| 1239 |
+
- [45, 21]
|
| 1240 |
+
- [46, 21]
|
| 1241 |
+
- [47, 21]
|
| 1242 |
+
- [48, 21]
|
| 1243 |
+
- [49, 21]
|
| 1244 |
+
- [50, 21]
|
| 1245 |
+
- [51, 21]
|
| 1246 |
+
- [52, 21]
|
| 1247 |
+
- [53, 21]
|
| 1248 |
+
- [54, 21]
|
| 1249 |
+
- [55, 21]
|
| 1250 |
+
- [56, 21]
|
| 1251 |
+
- [57, 21]
|
| 1252 |
+
- [58, 21]
|
| 1253 |
+
- [59, 21]
|
| 1254 |
+
- [60, 21]
|
| 1255 |
+
- [61, 21]
|
| 1256 |
+
- [62, 21]
|
| 1257 |
+
- [63, 21]
|
| 1258 |
+
- [64, 21]
|
| 1259 |
+
- [65, 21]
|
| 1260 |
+
- [66, 21]
|
| 1261 |
+
- [67, 21]
|
| 1262 |
+
- [68, 21]
|
| 1263 |
+
- [69, 21]
|
| 1264 |
+
- [70, 21]
|
| 1265 |
+
- [71, 21]
|
| 1266 |
+
- [72, 21]
|
| 1267 |
+
- [73, 21]
|
| 1268 |
+
- [74, 21]
|
| 1269 |
+
- [75, 21]
|
| 1270 |
+
- [76, 21]
|
| 1271 |
+
- [77, 21]
|
| 1272 |
+
- [78, 21]
|
| 1273 |
+
- [79, 21]
|
| 1274 |
+
- [80, 21]
|
| 1275 |
+
- [81, 21]
|
| 1276 |
+
- [86, 21]
|
| 1277 |
+
- [87, 21]
|
| 1278 |
+
- [88, 21]
|
| 1279 |
+
- [89, 21]
|
| 1280 |
+
- [90, 21]
|
| 1281 |
+
- [91, 21]
|
| 1282 |
+
- [92, 21]
|
| 1283 |
+
- [93, 21]
|
| 1284 |
+
- [94, 21]
|
| 1285 |
+
- [95, 21]
|
| 1286 |
+
- [96, 21]
|
| 1287 |
+
- [97, 21]
|
| 1288 |
+
- [98, 21]
|
| 1289 |
+
- [99, 21]
|
| 1290 |
+
- [100, 21]
|
| 1291 |
+
- [101, 21]
|
| 1292 |
+
- [102, 21]
|
| 1293 |
+
- [103, 21]
|
| 1294 |
+
- [104, 21]
|
| 1295 |
+
- [105, 21]
|
| 1296 |
+
- [106, 21]
|
| 1297 |
+
- [107, 21]
|
| 1298 |
+
- [108, 21]
|
| 1299 |
+
- [109, 21]
|
| 1300 |
+
- [110, 21]
|
| 1301 |
+
- [111, 21]
|
| 1302 |
+
- [112, 21]
|
| 1303 |
+
- [113, 21]
|
| 1304 |
+
- [114, 21]
|
| 1305 |
+
- [115, 21]
|
| 1306 |
+
- [116, 21]
|
| 1307 |
+
- [117, 21]
|
| 1308 |
+
- [118, 21]
|
| 1309 |
+
- [119, 21]
|
| 1310 |
+
- [120, 21]
|
| 1311 |
+
- [121, 21]
|
| 1312 |
+
- [122, 21]
|
| 1313 |
+
- [123, 21]
|
| 1314 |
+
- [124, 21]
|
| 1315 |
+
- [125, 21]
|
| 1316 |
+
- [126, 21]
|
| 1317 |
+
- [127, 21]
|
| 1318 |
+
win_condition:
|
| 1319 |
+
all_of:
|
| 1320 |
+
- units_killed_gte: 8
|
| 1321 |
+
- has_building: fact
|
| 1322 |
+
- within_ticks: 3150
|
| 1323 |
+
- building_count_gte:
|
| 1324 |
+
type: proc
|
| 1325 |
+
n: 2
|
| 1326 |
+
fail_condition:
|
| 1327 |
+
any_of:
|
| 1328 |
+
- after_ticks: 3151
|
| 1329 |
+
- not:
|
| 1330 |
+
has_building: fact
|
| 1331 |
+
- not:
|
| 1332 |
+
building_count_gte:
|
| 1333 |
+
type: proc
|
| 1334 |
+
n: 2
|
| 1335 |
+
max_turns: 40
|
| 1336 |
+
hard:
|
| 1337 |
+
description: Three bridges (west, centre, east) cross the water. Each bridge has a refinery (proc) directly behind it
|
| 1338 |
+
that the attackers will destroy if unopposed. Five riflemen attack through EACH bridge. Defenders are on HoldFire (stance
|
| 1339 |
+
0) at the centre. You must split into thirds + flip stance + intercept at all three bridges. Win = kill ≥10 attackers
|
| 1340 |
+
AND keep ALL THREE procs alive, before turn 40.
|
| 1341 |
+
starting_cash: 1000
|
| 1342 |
+
overrides:
|
| 1343 |
+
actors:
|
| 1344 |
+
- *id001
|
| 1345 |
+
- *id002
|
| 1346 |
+
- type: proc
|
| 1347 |
+
owner: agent
|
| 1348 |
+
position:
|
| 1349 |
+
- 28
|
| 1350 |
+
- 26
|
| 1351 |
+
- type: proc
|
| 1352 |
+
owner: agent
|
| 1353 |
+
position:
|
| 1354 |
+
- 60
|
| 1355 |
+
- 26
|
| 1356 |
+
- type: proc
|
| 1357 |
+
owner: agent
|
| 1358 |
+
position:
|
| 1359 |
+
- 92
|
| 1360 |
+
- 26
|
| 1361 |
+
- type: e1
|
| 1362 |
+
owner: agent
|
| 1363 |
+
position:
|
| 1364 |
+
- 58
|
| 1365 |
+
- 30
|
| 1366 |
+
stance: 0
|
| 1367 |
+
- type: e1
|
| 1368 |
+
owner: agent
|
| 1369 |
+
position:
|
| 1370 |
+
- 59
|
| 1371 |
+
- 30
|
| 1372 |
+
stance: 0
|
| 1373 |
+
- type: e1
|
| 1374 |
+
owner: agent
|
| 1375 |
+
position:
|
| 1376 |
+
- 60
|
| 1377 |
+
- 30
|
| 1378 |
+
stance: 0
|
| 1379 |
+
- type: e1
|
| 1380 |
+
owner: agent
|
| 1381 |
+
position:
|
| 1382 |
+
- 61
|
| 1383 |
+
- 30
|
| 1384 |
+
stance: 0
|
| 1385 |
+
- type: e1
|
| 1386 |
+
owner: agent
|
| 1387 |
+
position:
|
| 1388 |
+
- 62
|
| 1389 |
+
- 30
|
| 1390 |
+
stance: 0
|
| 1391 |
+
- type: e1
|
| 1392 |
+
owner: agent
|
| 1393 |
+
position:
|
| 1394 |
+
- 63
|
| 1395 |
+
- 30
|
| 1396 |
+
stance: 0
|
| 1397 |
+
- type: e1
|
| 1398 |
+
owner: agent
|
| 1399 |
+
position:
|
| 1400 |
+
- 64
|
| 1401 |
+
- 30
|
| 1402 |
+
stance: 0
|
| 1403 |
+
- type: e1
|
| 1404 |
+
owner: agent
|
| 1405 |
+
position:
|
| 1406 |
+
- 58
|
| 1407 |
+
- 31
|
| 1408 |
+
stance: 0
|
| 1409 |
+
- type: e1
|
| 1410 |
+
owner: agent
|
| 1411 |
+
position:
|
| 1412 |
+
- 59
|
| 1413 |
+
- 31
|
| 1414 |
+
stance: 0
|
| 1415 |
+
- type: e1
|
| 1416 |
+
owner: agent
|
| 1417 |
+
position:
|
| 1418 |
+
- 60
|
| 1419 |
+
- 31
|
| 1420 |
+
stance: 0
|
| 1421 |
+
- type: e1
|
| 1422 |
+
owner: agent
|
| 1423 |
+
position:
|
| 1424 |
+
- 61
|
| 1425 |
+
- 31
|
| 1426 |
+
stance: 0
|
| 1427 |
+
- type: e1
|
| 1428 |
+
owner: agent
|
| 1429 |
+
position:
|
| 1430 |
+
- 62
|
| 1431 |
+
- 31
|
| 1432 |
+
stance: 0
|
| 1433 |
+
- type: e1
|
| 1434 |
+
owner: agent
|
| 1435 |
+
position:
|
| 1436 |
+
- 63
|
| 1437 |
+
- 31
|
| 1438 |
+
stance: 0
|
| 1439 |
+
- type: e1
|
| 1440 |
+
owner: agent
|
| 1441 |
+
position:
|
| 1442 |
+
- 64
|
| 1443 |
+
- 31
|
| 1444 |
+
stance: 0
|
| 1445 |
+
- type: e1
|
| 1446 |
+
owner: agent
|
| 1447 |
+
position:
|
| 1448 |
+
- 58
|
| 1449 |
+
- 32
|
| 1450 |
+
stance: 0
|
| 1451 |
+
- type: e1
|
| 1452 |
+
owner: agent
|
| 1453 |
+
position:
|
| 1454 |
+
- 59
|
| 1455 |
+
- 32
|
| 1456 |
+
stance: 0
|
| 1457 |
+
- type: e1
|
| 1458 |
+
owner: agent
|
| 1459 |
+
position:
|
| 1460 |
+
- 60
|
| 1461 |
+
- 32
|
| 1462 |
+
stance: 0
|
| 1463 |
+
- type: e1
|
| 1464 |
+
owner: agent
|
| 1465 |
+
position:
|
| 1466 |
+
- 61
|
| 1467 |
+
- 32
|
| 1468 |
+
stance: 0
|
| 1469 |
+
- type: e1
|
| 1470 |
+
owner: enemy
|
| 1471 |
+
position:
|
| 1472 |
+
- 26
|
| 1473 |
+
- 4
|
| 1474 |
+
stance: 3
|
| 1475 |
+
- type: e1
|
| 1476 |
+
owner: enemy
|
| 1477 |
+
position:
|
| 1478 |
+
- 27
|
| 1479 |
+
- 4
|
| 1480 |
+
stance: 3
|
| 1481 |
+
- type: e1
|
| 1482 |
+
owner: enemy
|
| 1483 |
+
position:
|
| 1484 |
+
- 28
|
| 1485 |
+
- 4
|
| 1486 |
+
stance: 3
|
| 1487 |
+
- type: e1
|
| 1488 |
+
owner: enemy
|
| 1489 |
+
position:
|
| 1490 |
+
- 29
|
| 1491 |
+
- 4
|
| 1492 |
+
stance: 3
|
| 1493 |
+
- type: e1
|
| 1494 |
+
owner: enemy
|
| 1495 |
+
position:
|
| 1496 |
+
- 30
|
| 1497 |
+
- 4
|
| 1498 |
+
stance: 3
|
| 1499 |
+
- type: e1
|
| 1500 |
+
owner: enemy
|
| 1501 |
+
position:
|
| 1502 |
+
- 58
|
| 1503 |
+
- 4
|
| 1504 |
+
stance: 3
|
| 1505 |
+
- type: e1
|
| 1506 |
+
owner: enemy
|
| 1507 |
+
position:
|
| 1508 |
+
- 59
|
| 1509 |
+
- 4
|
| 1510 |
+
stance: 3
|
| 1511 |
+
- type: e1
|
| 1512 |
+
owner: enemy
|
| 1513 |
+
position:
|
| 1514 |
+
- 60
|
| 1515 |
+
- 4
|
| 1516 |
+
stance: 3
|
| 1517 |
+
- type: e1
|
| 1518 |
+
owner: enemy
|
| 1519 |
+
position:
|
| 1520 |
+
- 61
|
| 1521 |
+
- 4
|
| 1522 |
+
stance: 3
|
| 1523 |
+
- type: e1
|
| 1524 |
+
owner: enemy
|
| 1525 |
+
position:
|
| 1526 |
+
- 62
|
| 1527 |
+
- 4
|
| 1528 |
+
stance: 3
|
| 1529 |
+
- type: e1
|
| 1530 |
+
owner: enemy
|
| 1531 |
+
position:
|
| 1532 |
+
- 90
|
| 1533 |
+
- 4
|
| 1534 |
+
stance: 3
|
| 1535 |
+
- type: e1
|
| 1536 |
+
owner: enemy
|
| 1537 |
+
position:
|
| 1538 |
+
- 91
|
| 1539 |
+
- 4
|
| 1540 |
+
stance: 3
|
| 1541 |
+
- type: e1
|
| 1542 |
+
owner: enemy
|
| 1543 |
+
position:
|
| 1544 |
+
- 92
|
| 1545 |
+
- 4
|
| 1546 |
+
stance: 3
|
| 1547 |
+
- type: e1
|
| 1548 |
+
owner: enemy
|
| 1549 |
+
position:
|
| 1550 |
+
- 93
|
| 1551 |
+
- 4
|
| 1552 |
+
stance: 3
|
| 1553 |
+
- type: e1
|
| 1554 |
+
owner: enemy
|
| 1555 |
+
position:
|
| 1556 |
+
- 94
|
| 1557 |
+
- 4
|
| 1558 |
+
stance: 3
|
| 1559 |
+
- type: fact
|
| 1560 |
+
owner: enemy
|
| 1561 |
+
position:
|
| 1562 |
+
- 120
|
| 1563 |
+
- 4
|
| 1564 |
+
water_cells:
|
| 1565 |
+
- [0, 18]
|
| 1566 |
+
- [1, 18]
|
| 1567 |
+
- [2, 18]
|
| 1568 |
+
- [3, 18]
|
| 1569 |
+
- [4, 18]
|
| 1570 |
+
- [5, 18]
|
| 1571 |
+
- [6, 18]
|
| 1572 |
+
- [7, 18]
|
| 1573 |
+
- [8, 18]
|
| 1574 |
+
- [9, 18]
|
| 1575 |
+
- [10, 18]
|
| 1576 |
+
- [11, 18]
|
| 1577 |
+
- [12, 18]
|
| 1578 |
+
- [13, 18]
|
| 1579 |
+
- [14, 18]
|
| 1580 |
+
- [15, 18]
|
| 1581 |
+
- [16, 18]
|
| 1582 |
+
- [17, 18]
|
| 1583 |
+
- [18, 18]
|
| 1584 |
+
- [19, 18]
|
| 1585 |
+
- [20, 18]
|
| 1586 |
+
- [21, 18]
|
| 1587 |
+
- [22, 18]
|
| 1588 |
+
- [23, 18]
|
| 1589 |
+
- [24, 18]
|
| 1590 |
+
- [25, 18]
|
| 1591 |
+
- [26, 18]
|
| 1592 |
+
- [27, 18]
|
| 1593 |
+
- [32, 18]
|
| 1594 |
+
- [33, 18]
|
| 1595 |
+
- [34, 18]
|
| 1596 |
+
- [35, 18]
|
| 1597 |
+
- [36, 18]
|
| 1598 |
+
- [37, 18]
|
| 1599 |
+
- [38, 18]
|
| 1600 |
+
- [39, 18]
|
| 1601 |
+
- [40, 18]
|
| 1602 |
+
- [41, 18]
|
| 1603 |
+
- [42, 18]
|
| 1604 |
+
- [43, 18]
|
| 1605 |
+
- [44, 18]
|
| 1606 |
+
- [45, 18]
|
| 1607 |
+
- [46, 18]
|
| 1608 |
+
- [47, 18]
|
| 1609 |
+
- [48, 18]
|
| 1610 |
+
- [49, 18]
|
| 1611 |
+
- [50, 18]
|
| 1612 |
+
- [51, 18]
|
| 1613 |
+
- [52, 18]
|
| 1614 |
+
- [53, 18]
|
| 1615 |
+
- [54, 18]
|
| 1616 |
+
- [55, 18]
|
| 1617 |
+
- [56, 18]
|
| 1618 |
+
- [57, 18]
|
| 1619 |
+
- [58, 18]
|
| 1620 |
+
- [59, 18]
|
| 1621 |
+
- [64, 18]
|
| 1622 |
+
- [65, 18]
|
| 1623 |
+
- [66, 18]
|
| 1624 |
+
- [67, 18]
|
| 1625 |
+
- [68, 18]
|
| 1626 |
+
- [69, 18]
|
| 1627 |
+
- [70, 18]
|
| 1628 |
+
- [71, 18]
|
| 1629 |
+
- [72, 18]
|
| 1630 |
+
- [73, 18]
|
| 1631 |
+
- [74, 18]
|
| 1632 |
+
- [75, 18]
|
| 1633 |
+
- [76, 18]
|
| 1634 |
+
- [77, 18]
|
| 1635 |
+
- [78, 18]
|
| 1636 |
+
- [79, 18]
|
| 1637 |
+
- [80, 18]
|
| 1638 |
+
- [81, 18]
|
| 1639 |
+
- [82, 18]
|
| 1640 |
+
- [83, 18]
|
| 1641 |
+
- [84, 18]
|
| 1642 |
+
- [85, 18]
|
| 1643 |
+
- [86, 18]
|
| 1644 |
+
- [87, 18]
|
| 1645 |
+
- [88, 18]
|
| 1646 |
+
- [89, 18]
|
| 1647 |
+
- [90, 18]
|
| 1648 |
+
- [91, 18]
|
| 1649 |
+
- [96, 18]
|
| 1650 |
+
- [97, 18]
|
| 1651 |
+
- [98, 18]
|
| 1652 |
+
- [99, 18]
|
| 1653 |
+
- [100, 18]
|
| 1654 |
+
- [101, 18]
|
| 1655 |
+
- [102, 18]
|
| 1656 |
+
- [103, 18]
|
| 1657 |
+
- [104, 18]
|
| 1658 |
+
- [105, 18]
|
| 1659 |
+
- [106, 18]
|
| 1660 |
+
- [107, 18]
|
| 1661 |
+
- [108, 18]
|
| 1662 |
+
- [109, 18]
|
| 1663 |
+
- [110, 18]
|
| 1664 |
+
- [111, 18]
|
| 1665 |
+
- [112, 18]
|
| 1666 |
+
- [113, 18]
|
| 1667 |
+
- [114, 18]
|
| 1668 |
+
- [115, 18]
|
| 1669 |
+
- [116, 18]
|
| 1670 |
+
- [117, 18]
|
| 1671 |
+
- [118, 18]
|
| 1672 |
+
- [119, 18]
|
| 1673 |
+
- [120, 18]
|
| 1674 |
+
- [121, 18]
|
| 1675 |
+
- [122, 18]
|
| 1676 |
+
- [123, 18]
|
| 1677 |
+
- [124, 18]
|
| 1678 |
+
- [125, 18]
|
| 1679 |
+
- [126, 18]
|
| 1680 |
+
- [127, 18]
|
| 1681 |
+
- [0, 19]
|
| 1682 |
+
- [1, 19]
|
| 1683 |
+
- [2, 19]
|
| 1684 |
+
- [3, 19]
|
| 1685 |
+
- [4, 19]
|
| 1686 |
+
- [5, 19]
|
| 1687 |
+
- [6, 19]
|
| 1688 |
+
- [7, 19]
|
| 1689 |
+
- [8, 19]
|
| 1690 |
+
- [9, 19]
|
| 1691 |
+
- [10, 19]
|
| 1692 |
+
- [11, 19]
|
| 1693 |
+
- [12, 19]
|
| 1694 |
+
- [13, 19]
|
| 1695 |
+
- [14, 19]
|
| 1696 |
+
- [15, 19]
|
| 1697 |
+
- [16, 19]
|
| 1698 |
+
- [17, 19]
|
| 1699 |
+
- [18, 19]
|
| 1700 |
+
- [19, 19]
|
| 1701 |
+
- [20, 19]
|
| 1702 |
+
- [21, 19]
|
| 1703 |
+
- [22, 19]
|
| 1704 |
+
- [23, 19]
|
| 1705 |
+
- [24, 19]
|
| 1706 |
+
- [25, 19]
|
| 1707 |
+
- [26, 19]
|
| 1708 |
+
- [27, 19]
|
| 1709 |
+
- [32, 19]
|
| 1710 |
+
- [33, 19]
|
| 1711 |
+
- [34, 19]
|
| 1712 |
+
- [35, 19]
|
| 1713 |
+
- [36, 19]
|
| 1714 |
+
- [37, 19]
|
| 1715 |
+
- [38, 19]
|
| 1716 |
+
- [39, 19]
|
| 1717 |
+
- [40, 19]
|
| 1718 |
+
- [41, 19]
|
| 1719 |
+
- [42, 19]
|
| 1720 |
+
- [43, 19]
|
| 1721 |
+
- [44, 19]
|
| 1722 |
+
- [45, 19]
|
| 1723 |
+
- [46, 19]
|
| 1724 |
+
- [47, 19]
|
| 1725 |
+
- [48, 19]
|
| 1726 |
+
- [49, 19]
|
| 1727 |
+
- [50, 19]
|
| 1728 |
+
- [51, 19]
|
| 1729 |
+
- [52, 19]
|
| 1730 |
+
- [53, 19]
|
| 1731 |
+
- [54, 19]
|
| 1732 |
+
- [55, 19]
|
| 1733 |
+
- [56, 19]
|
| 1734 |
+
- [57, 19]
|
| 1735 |
+
- [58, 19]
|
| 1736 |
+
- [59, 19]
|
| 1737 |
+
- [64, 19]
|
| 1738 |
+
- [65, 19]
|
| 1739 |
+
- [66, 19]
|
| 1740 |
+
- [67, 19]
|
| 1741 |
+
- [68, 19]
|
| 1742 |
+
- [69, 19]
|
| 1743 |
+
- [70, 19]
|
| 1744 |
+
- [71, 19]
|
| 1745 |
+
- [72, 19]
|
| 1746 |
+
- [73, 19]
|
| 1747 |
+
- [74, 19]
|
| 1748 |
+
- [75, 19]
|
| 1749 |
+
- [76, 19]
|
| 1750 |
+
- [77, 19]
|
| 1751 |
+
- [78, 19]
|
| 1752 |
+
- [79, 19]
|
| 1753 |
+
- [80, 19]
|
| 1754 |
+
- [81, 19]
|
| 1755 |
+
- [82, 19]
|
| 1756 |
+
- [83, 19]
|
| 1757 |
+
- [84, 19]
|
| 1758 |
+
- [85, 19]
|
| 1759 |
+
- [86, 19]
|
| 1760 |
+
- [87, 19]
|
| 1761 |
+
- [88, 19]
|
| 1762 |
+
- [89, 19]
|
| 1763 |
+
- [90, 19]
|
| 1764 |
+
- [91, 19]
|
| 1765 |
+
- [96, 19]
|
| 1766 |
+
- [97, 19]
|
| 1767 |
+
- [98, 19]
|
| 1768 |
+
- [99, 19]
|
| 1769 |
+
- [100, 19]
|
| 1770 |
+
- [101, 19]
|
| 1771 |
+
- [102, 19]
|
| 1772 |
+
- [103, 19]
|
| 1773 |
+
- [104, 19]
|
| 1774 |
+
- [105, 19]
|
| 1775 |
+
- [106, 19]
|
| 1776 |
+
- [107, 19]
|
| 1777 |
+
- [108, 19]
|
| 1778 |
+
- [109, 19]
|
| 1779 |
+
- [110, 19]
|
| 1780 |
+
- [111, 19]
|
| 1781 |
+
- [112, 19]
|
| 1782 |
+
- [113, 19]
|
| 1783 |
+
- [114, 19]
|
| 1784 |
+
- [115, 19]
|
| 1785 |
+
- [116, 19]
|
| 1786 |
+
- [117, 19]
|
| 1787 |
+
- [118, 19]
|
| 1788 |
+
- [119, 19]
|
| 1789 |
+
- [120, 19]
|
| 1790 |
+
- [121, 19]
|
| 1791 |
+
- [122, 19]
|
| 1792 |
+
- [123, 19]
|
| 1793 |
+
- [124, 19]
|
| 1794 |
+
- [125, 19]
|
| 1795 |
+
- [126, 19]
|
| 1796 |
+
- [127, 19]
|
| 1797 |
+
- [0, 20]
|
| 1798 |
+
- [1, 20]
|
| 1799 |
+
- [2, 20]
|
| 1800 |
+
- [3, 20]
|
| 1801 |
+
- [4, 20]
|
| 1802 |
+
- [5, 20]
|
| 1803 |
+
- [6, 20]
|
| 1804 |
+
- [7, 20]
|
| 1805 |
+
- [8, 20]
|
| 1806 |
+
- [9, 20]
|
| 1807 |
+
- [10, 20]
|
| 1808 |
+
- [11, 20]
|
| 1809 |
+
- [12, 20]
|
| 1810 |
+
- [13, 20]
|
| 1811 |
+
- [14, 20]
|
| 1812 |
+
- [15, 20]
|
| 1813 |
+
- [16, 20]
|
| 1814 |
+
- [17, 20]
|
| 1815 |
+
- [18, 20]
|
| 1816 |
+
- [19, 20]
|
| 1817 |
+
- [20, 20]
|
| 1818 |
+
- [21, 20]
|
| 1819 |
+
- [22, 20]
|
| 1820 |
+
- [23, 20]
|
| 1821 |
+
- [24, 20]
|
| 1822 |
+
- [25, 20]
|
| 1823 |
+
- [26, 20]
|
| 1824 |
+
- [27, 20]
|
| 1825 |
+
- [32, 20]
|
| 1826 |
+
- [33, 20]
|
| 1827 |
+
- [34, 20]
|
| 1828 |
+
- [35, 20]
|
| 1829 |
+
- [36, 20]
|
| 1830 |
+
- [37, 20]
|
| 1831 |
+
- [38, 20]
|
| 1832 |
+
- [39, 20]
|
| 1833 |
+
- [40, 20]
|
| 1834 |
+
- [41, 20]
|
| 1835 |
+
- [42, 20]
|
| 1836 |
+
- [43, 20]
|
| 1837 |
+
- [44, 20]
|
| 1838 |
+
- [45, 20]
|
| 1839 |
+
- [46, 20]
|
| 1840 |
+
- [47, 20]
|
| 1841 |
+
- [48, 20]
|
| 1842 |
+
- [49, 20]
|
| 1843 |
+
- [50, 20]
|
| 1844 |
+
- [51, 20]
|
| 1845 |
+
- [52, 20]
|
| 1846 |
+
- [53, 20]
|
| 1847 |
+
- [54, 20]
|
| 1848 |
+
- [55, 20]
|
| 1849 |
+
- [56, 20]
|
| 1850 |
+
- [57, 20]
|
| 1851 |
+
- [58, 20]
|
| 1852 |
+
- [59, 20]
|
| 1853 |
+
- [64, 20]
|
| 1854 |
+
- [65, 20]
|
| 1855 |
+
- [66, 20]
|
| 1856 |
+
- [67, 20]
|
| 1857 |
+
- [68, 20]
|
| 1858 |
+
- [69, 20]
|
| 1859 |
+
- [70, 20]
|
| 1860 |
+
- [71, 20]
|
| 1861 |
+
- [72, 20]
|
| 1862 |
+
- [73, 20]
|
| 1863 |
+
- [74, 20]
|
| 1864 |
+
- [75, 20]
|
| 1865 |
+
- [76, 20]
|
| 1866 |
+
- [77, 20]
|
| 1867 |
+
- [78, 20]
|
| 1868 |
+
- [79, 20]
|
| 1869 |
+
- [80, 20]
|
| 1870 |
+
- [81, 20]
|
| 1871 |
+
- [82, 20]
|
| 1872 |
+
- [83, 20]
|
| 1873 |
+
- [84, 20]
|
| 1874 |
+
- [85, 20]
|
| 1875 |
+
- [86, 20]
|
| 1876 |
+
- [87, 20]
|
| 1877 |
+
- [88, 20]
|
| 1878 |
+
- [89, 20]
|
| 1879 |
+
- [90, 20]
|
| 1880 |
+
- [91, 20]
|
| 1881 |
+
- [96, 20]
|
| 1882 |
+
- [97, 20]
|
| 1883 |
+
- [98, 20]
|
| 1884 |
+
- [99, 20]
|
| 1885 |
+
- [100, 20]
|
| 1886 |
+
- [101, 20]
|
| 1887 |
+
- [102, 20]
|
| 1888 |
+
- [103, 20]
|
| 1889 |
+
- [104, 20]
|
| 1890 |
+
- [105, 20]
|
| 1891 |
+
- [106, 20]
|
| 1892 |
+
- [107, 20]
|
| 1893 |
+
- [108, 20]
|
| 1894 |
+
- [109, 20]
|
| 1895 |
+
- [110, 20]
|
| 1896 |
+
- [111, 20]
|
| 1897 |
+
- [112, 20]
|
| 1898 |
+
- [113, 20]
|
| 1899 |
+
- [114, 20]
|
| 1900 |
+
- [115, 20]
|
| 1901 |
+
- [116, 20]
|
| 1902 |
+
- [117, 20]
|
| 1903 |
+
- [118, 20]
|
| 1904 |
+
- [119, 20]
|
| 1905 |
+
- [120, 20]
|
| 1906 |
+
- [121, 20]
|
| 1907 |
+
- [122, 20]
|
| 1908 |
+
- [123, 20]
|
| 1909 |
+
- [124, 20]
|
| 1910 |
+
- [125, 20]
|
| 1911 |
+
- [126, 20]
|
| 1912 |
+
- [127, 20]
|
| 1913 |
+
- [0, 21]
|
| 1914 |
+
- [1, 21]
|
| 1915 |
+
- [2, 21]
|
| 1916 |
+
- [3, 21]
|
| 1917 |
+
- [4, 21]
|
| 1918 |
+
- [5, 21]
|
| 1919 |
+
- [6, 21]
|
| 1920 |
+
- [7, 21]
|
| 1921 |
+
- [8, 21]
|
| 1922 |
+
- [9, 21]
|
| 1923 |
+
- [10, 21]
|
| 1924 |
+
- [11, 21]
|
| 1925 |
+
- [12, 21]
|
| 1926 |
+
- [13, 21]
|
| 1927 |
+
- [14, 21]
|
| 1928 |
+
- [15, 21]
|
| 1929 |
+
- [16, 21]
|
| 1930 |
+
- [17, 21]
|
| 1931 |
+
- [18, 21]
|
| 1932 |
+
- [19, 21]
|
| 1933 |
+
- [20, 21]
|
| 1934 |
+
- [21, 21]
|
| 1935 |
+
- [22, 21]
|
| 1936 |
+
- [23, 21]
|
| 1937 |
+
- [24, 21]
|
| 1938 |
+
- [25, 21]
|
| 1939 |
+
- [26, 21]
|
| 1940 |
+
- [27, 21]
|
| 1941 |
+
- [32, 21]
|
| 1942 |
+
- [33, 21]
|
| 1943 |
+
- [34, 21]
|
| 1944 |
+
- [35, 21]
|
| 1945 |
+
- [36, 21]
|
| 1946 |
+
- [37, 21]
|
| 1947 |
+
- [38, 21]
|
| 1948 |
+
- [39, 21]
|
| 1949 |
+
- [40, 21]
|
| 1950 |
+
- [41, 21]
|
| 1951 |
+
- [42, 21]
|
| 1952 |
+
- [43, 21]
|
| 1953 |
+
- [44, 21]
|
| 1954 |
+
- [45, 21]
|
| 1955 |
+
- [46, 21]
|
| 1956 |
+
- [47, 21]
|
| 1957 |
+
- [48, 21]
|
| 1958 |
+
- [49, 21]
|
| 1959 |
+
- [50, 21]
|
| 1960 |
+
- [51, 21]
|
| 1961 |
+
- [52, 21]
|
| 1962 |
+
- [53, 21]
|
| 1963 |
+
- [54, 21]
|
| 1964 |
+
- [55, 21]
|
| 1965 |
+
- [56, 21]
|
| 1966 |
+
- [57, 21]
|
| 1967 |
+
- [58, 21]
|
| 1968 |
+
- [59, 21]
|
| 1969 |
+
- [64, 21]
|
| 1970 |
+
- [65, 21]
|
| 1971 |
+
- [66, 21]
|
| 1972 |
+
- [67, 21]
|
| 1973 |
+
- [68, 21]
|
| 1974 |
+
- [69, 21]
|
| 1975 |
+
- [70, 21]
|
| 1976 |
+
- [71, 21]
|
| 1977 |
+
- [72, 21]
|
| 1978 |
+
- [73, 21]
|
| 1979 |
+
- [74, 21]
|
| 1980 |
+
- [75, 21]
|
| 1981 |
+
- [76, 21]
|
| 1982 |
+
- [77, 21]
|
| 1983 |
+
- [78, 21]
|
| 1984 |
+
- [79, 21]
|
| 1985 |
+
- [80, 21]
|
| 1986 |
+
- [81, 21]
|
| 1987 |
+
- [82, 21]
|
| 1988 |
+
- [83, 21]
|
| 1989 |
+
- [84, 21]
|
| 1990 |
+
- [85, 21]
|
| 1991 |
+
- [86, 21]
|
| 1992 |
+
- [87, 21]
|
| 1993 |
+
- [88, 21]
|
| 1994 |
+
- [89, 21]
|
| 1995 |
+
- [90, 21]
|
| 1996 |
+
- [91, 21]
|
| 1997 |
+
- [96, 21]
|
| 1998 |
+
- [97, 21]
|
| 1999 |
+
- [98, 21]
|
| 2000 |
+
- [99, 21]
|
| 2001 |
+
- [100, 21]
|
| 2002 |
+
- [101, 21]
|
| 2003 |
+
- [102, 21]
|
| 2004 |
+
- [103, 21]
|
| 2005 |
+
- [104, 21]
|
| 2006 |
+
- [105, 21]
|
| 2007 |
+
- [106, 21]
|
| 2008 |
+
- [107, 21]
|
| 2009 |
+
- [108, 21]
|
| 2010 |
+
- [109, 21]
|
| 2011 |
+
- [110, 21]
|
| 2012 |
+
- [111, 21]
|
| 2013 |
+
- [112, 21]
|
| 2014 |
+
- [113, 21]
|
| 2015 |
+
- [114, 21]
|
| 2016 |
+
- [115, 21]
|
| 2017 |
+
- [116, 21]
|
| 2018 |
+
- [117, 21]
|
| 2019 |
+
- [118, 21]
|
| 2020 |
+
- [119, 21]
|
| 2021 |
+
- [120, 21]
|
| 2022 |
+
- [121, 21]
|
| 2023 |
+
- [122, 21]
|
| 2024 |
+
- [123, 21]
|
| 2025 |
+
- [124, 21]
|
| 2026 |
+
- [125, 21]
|
| 2027 |
+
- [126, 21]
|
| 2028 |
+
- [127, 21]
|
| 2029 |
+
win_condition:
|
| 2030 |
+
all_of:
|
| 2031 |
+
- units_killed_gte: 10
|
| 2032 |
+
- has_building: fact
|
| 2033 |
+
- within_ticks: 3600
|
| 2034 |
+
- building_count_gte:
|
| 2035 |
+
type: proc
|
| 2036 |
+
n: 3
|
| 2037 |
+
fail_condition:
|
| 2038 |
+
any_of:
|
| 2039 |
+
- after_ticks: 3601
|
| 2040 |
+
- not:
|
| 2041 |
+
has_building: fact
|
| 2042 |
+
- not:
|
| 2043 |
+
building_count_gte:
|
| 2044 |
+
type: proc
|
| 2045 |
+
n: 3
|
| 2046 |
+
max_turns: 45
|