diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 9f2d634..4c22c57 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -546,6 +546,20 @@ search cannot find a *schedule*. line in every run reads `UN_e007_ADAN_Turret`, because `SYLPH_HUNT`/`KEEPOUT` were built for turrets. **42 kills were the wrong 42.** **Test: a pilot that prioritises `e010` over `e007`**, watching `deployed` jump from 41. +* ✅🚧 **(2026-08-24) `SYLPH_PREFER` works; the blocker is now COMBAT, not RE.** + Preference knob added (matching units ×0.05, others ×4.0). One clean 320 s run + (**0 stalls**): 8 turret kills vs **2** `e010` — real effect (was ~1 across ALL + prior runs) but weak; commitment + proximity keep pulling back to turrets, which + outnumber attackers 108:16 in craft. `deployed` stayed **41**, no advance. + 🚧 **Quantified blocker:** phase 1 fields **16** `Attacker_S` craft; at 2 per + 320 s clearing them needs **~2560 s ≈ 43 min** of verified-live flight across + many chained attaches, against a ~2-in-5 freeze rate. + **Everything needed to OBSERVE the advance is built and validated** — roster + link, liveness, stall witness, chained attaches, discard rule. What is missing + is a pilot good enough to finish the objective. **User's choice:** (1) invest in + the pilot (game-playing, uncertain); (2) accept the static answer (structure, + rosters, routes, objective texts all decoded and cross-confirmed; only the + *trigger* is inferred); (3) one 40+ min chained run betting against freezes. 🔴 `SYLPH_HZ=3` refuted as a lever: it gave the LOWEST frame rate (8/s) with the most kills, so pilot polling is not the throttle. * ~~🚧 BLOCKER: t=210/240 unreachable in one turn~~ — **superseded, see above**; diff --git a/docs/re/mission-objectives-text.md b/docs/re/mission-objectives-text.md index 99c7b50..405b26f 100644 --- a/docs/re/mission-objectives-text.md +++ b/docs/re/mission-objectives-text.md @@ -73,3 +73,63 @@ not new decoding — and the existing probe watching `deployed`. This is 🟡, not ✅: the objective text is certain, but that *this particular objective* gates the phase advance is inference from the script's structure. + +--- + +# The target-preference knob works, and the blocker is now combat, not RE (2026-08-24) + +## ✅ `SYLPH_PREFER` added and measured + +`pilot.py` gained a target-preference knob: a unit-name substring whose matches +get their target score multiplied by 0.05 and everything else by 4.0. With +`SYLPH_PREFER=e010`, one clean 320 s run (witness: **0 stalls**): + +| killed | count | +|---|---| +| `UN_e007_ADAN_Turret` | 8 | +| `UN_e010_ADAN_Attacker_S` | **2** | + +The preference is real — `e010` kills went from about one *across all previous +runs* to two in a single run — but it is **weak**: turrets still outnumber +attackers 4:1 in the kill log. Target commitment (`COMMIT_MAX`, `COMMIT_DROP`) +and simple proximity keep pulling the nose back to turrets, which are far more +numerous. + +`deployed` stayed at **41** throughout. No phase advance. + +## 🚧 The blocker, quantified + +Phase 1's roster, by craft rather than by squadron: + +| unit | members | craft (`sum(n)`) | +|---|---|---| +| `UN_e007_ADAN_Turret` | 12 | **108** | +| `UN_e106_ADAN_Destroyer` | 7 | 7 | +| `UN_f001_TCAF_DeltaSaber_T` | 7 | 7 | +| **`UN_e010_ADAN_Attacker_S`** | **4** | **16** | + +Clearing the marked attackers means destroying **16 craft**. At the measured rate +of 2 per 320 s that is **~2560 s — roughly 43 minutes** of continuous +verified-live flight, across many chained attaches, with a freeze rate of about +two runs in five. + +**This is no longer a reverse-engineering problem.** Everything needed to observe +the phase advance is built and validated: the roster link, the liveness read, the +stall witness, chained attaches, the discard rule. What is missing is a pilot +good enough to actually complete the mission objective, and that is game-playing +work with an uncertain payoff. + +## The choice, which is the user's to make + +1. **Invest in the pilot** — better target selection, missiles, using the + marker/lock the script keeps referring to. Uncertain, potentially several + iterations, and drifts away from RE. +2. **Accept the static answer.** The phase structure, per-phase rosters, route + paths and objective texts are all decoded and cross-confirmed. Only the + *trigger* is inferred rather than observed, and it is inferred from the game's + own guide script naming the objective outright. +3. **One very long run** — 40+ minutes of chained attaches — betting against the + freeze rate. + +Recorded rather than chosen, because it is a question about how much effort this +one confirmation is worth, not a technical unknown. diff --git a/tools/re-capture/pilot.py b/tools/re-capture/pilot.py index dd4bcda..79abfdd 100644 --- a/tools/re-capture/pilot.py +++ b/tools/re-capture/pilot.py @@ -114,6 +114,7 @@ KILL_TURRETS = os.environ.get("SYLPH_KILL_TURRETS") == "1" HUNT = os.environ.get("SYLPH_HUNT") == "1" +PREFER = os.environ.get("SYLPH_PREFER", "") class Pilot: @@ -389,6 +390,15 @@ class Pilot: lead = self.lead_point(p, v, d) theta = ang(lead - me_p, fwd) score = d * (1.0 + 3.0 * (theta / math.pi) ** 2) + # SYLPH_PREFER biases target choice toward a unit-name substring. + # Stage 02's phase-1 objective is stated outright in the guide + # script -- "the attackers with the orange markers" -- i.e. e010, + # but every kill in every run so far was an e007 turret, because + # HUNT made turrets targets and KEEPOUT was tuned for them + # (mission-objectives-text.md). Without this the pilot cannot be + # pointed at the thing the mission actually asks for. + if PREFER: + score *= 0.05 if PREFER in nm else 4.0 if score < bestscore: best, bestscore = (off, nm, lead, lead - me_p, d, r), score return best diff --git a/tools/re-capture/wave7_session.sh b/tools/re-capture/wave7_session.sh index e100655..68f7b56 100755 --- a/tools/re-capture/wave7_session.sh +++ b/tools/re-capture/wave7_session.sh @@ -22,7 +22,7 @@ for try in 1 2 3; do echo "--- bind attempt $try failed, retrying"; sleep 5 done if [ "$BOUND" = 1 ]; then - SYLPH_HUNT="$HUNT" SYLPH_KILL_TURRETS=1 SYLPH_KEEPOUT="${SYLPH_KEEPOUT:-1400}" SYLPH_HZ="${SYLPH_HZ:-8.0}" nohup python3 "$SD/pilot.py" "$CFG" "$SECS" \ + SYLPH_HUNT="$HUNT" SYLPH_KILL_TURRETS=1 SYLPH_KEEPOUT="${SYLPH_KEEPOUT:-1400}" SYLPH_HZ="${SYLPH_HZ:-8.0}" SYLPH_PREFER="${SYLPH_PREFER:-}" nohup python3 "$SD/pilot.py" "$CFG" "$SECS" \ /tmp/live-pilot.log 2>&1 & PILOT=$!; echo "--- pilot (SYLPH_HUNT=$HUNT)" else echo "BIND FAILED after 3 attempts -- aborting, an unattended run tests nothing"; exit 4; fi