Repository navigation
feat(farming): rank farm spots with the locked farming analyzer - #46
Conversation
Pin the atrinik/tools farming analyzer and the Classic server source it reads, run it in the background from the character's live combat profile, and add a dashboard Farming tab with a saved objective toggle (XP, money or loot per hour, balanced, safety). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f3ea3cf47
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…hanges Let `dependencies` take pre-downloaded --analyzer-archive and --server-archive files for air-gapped installs, and treat a 5% change in character speed as a material profile change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f73336f4b7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Track when the current report was produced separately from the last attempt, so a failed six-hour refresh is retried after fifteen minutes instead of waiting almost another six hours. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
🎉 This PR is included in version 1.21.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
## Summary Follows #46 (merged), which pins and runs the farming analyzer. Autoplay now always farms the farming analyzer's #1 spot for the dashboard's preferred objective (XP, money or loot per hour, balanced, or safety). The hard-coded level ladder and every curated spot are gone: - **Removed:** all 38 `FarmCircuitTask` tier tables (`EARLY_*`, `TREE_*`, `UNDERGROUND_CITY_*`, `ZECHNA_*`, deer, Strakewood, Fort Sether, wizardry catch-up, …), together with: - `_progression_legs`, `_safe_progression_legs`, `_catchup_progression_legs`; - the deer and Strakewood readiness gates and guarded trials; - the level-specific leg exceptions (killer bees, ogres, early lost souls); - the per-map safety switch; - `farm_spots.py`. In all, 1,491 lines removed. - **`analyzer_farm_selection(client, graph)`:** returns the preferred objective's highest-ranked spot whose maps all exist in the world graph and none of which is quarantined. `analyzer_spot_legs` turns its `map_paths` into legs (a multi-map circuit rotates through every map, as before) and its monster labels (`giant frog L20×3`) into the target pattern. - **Autoplay:** waits safely, recording one `awaiting-farm-ranking` decision, until a spot exists. Then it starts an `analyzer_driven` circuit, which re-selects whenever the ranking, the objective or a quarantine changes, between fights and loot. Each switch records a `farm-spot-selected` decision. - **Safety from analyzer data:** spots with aggressive residents get flee 0.80 and heal 0.95, plus the isolated-radius pull planner (one resident at a time, from squares outside the others' detection radii). Before, only `world_1_50` had it. Other spots use 0.75 and 0.90. The lost-soul margin stays as a floor. Explicit, non-analyzer circuits keep their previous behaviour. - **Dashboard:** the Tasks tab's **Farm** picker lists the same ranked spots. Starting one sends its `analyzer_spot` id; the server rebuilds the circuit from its own ranking (rejecting a spot that's no longer ranked) with that spot's analyzer-derived margins and pulls. A manual pick stays on its spot instead of following later rankings. - **Nothing usable left:** if every ranked spot is quarantined or unusable while the current spot is excluded, the circuit records `farm-spots-exhausted` and finishes. Autoplay then holds position safely until a usable spot is ranked again; it never keeps farming a spot that was just excluded. ### The only exceptions: live failures As agreed, the analyzer is the source of truth. A spot is excluded for six hours, and autoplay moves to the next-ranked one, only after something it couldn't model goes wrong there: - **Agreed:** a death there, including on the way there; an emergency recall there. - **Beyond what was agreed (flagging for your review):** - ten minutes on the spot without any character XP. This watchdog used to apply only at level 30+, which is how Sera stalled at 0 XP on world_14_77. Time away from the farm (maintenance, travel, reconnects) restarts the clock instead of counting against the spot; - a route the world graph cannot plan. Otherwise an unreachable #1 would fail autoplay repeatedly. Only failures recorded after the circuit started count, so a decision ledger replayed after a restart can't extend an expired quarantine. ### What she'll do live With Sera's real stats (slash weapons 22, DAM 44, WC 31, HP 188, AC 37), the real analyzer and world graph pick the following. Every ranked spot maps onto the graph. | Objective | Spot | Margins | Pulls | | --- | --- | --- | --- | | XP, loot, balanced, safety | Strakewood Island circuit: world_0_50, 0_51, 1_50, 1_51, targeting crocodile, giant frog and mud hand | 0.80 / 0.95 | isolated | | Money | Eld Woods Island circuit: world_13_73 and 14_73, targeting giant slug and red ant | 0.75 / 0.90 | adjacent | The Strakewood circuit is where crocodile and frog packs killed Sera before. The cautious margins, isolated pulls and the death/emergency-recall quarantine are the safety net. If she dies there again, the analyzer's danger model needs to learn about those joins. ## Validation - Full suite on a fresh CMake build: 444 tests OK. - **Removed:** 19 tier-policy tests (ladders, readiness, catch-up, guarded trials, hand-audited exclusions, the Old Outpost per-map margin, the spot catalog). - **Converted:** mechanics tests now use literal legs: patrol squares, the rare-detour cooldown, unreachable-target cooldown, waiting for an engaged target, launcher rules, and combat-build review. - **New tests:** - analyzer results mapping to legs and targets; - selection following the objective and skipping quarantines; - autoplay waiting for a spot; - death and emergency recall each quarantining the pick and re-selecting, without blaming a reached pick for a death elsewhere; - the ten-minute no-XP watchdog for any analyzer pick; - an unreachable pick being excluded instead of failing autoplay; - the data-driven margins. - An end-to-end probe with the real analyzer, cached bundle and world graph produced the table above. - `node --check web_static/app.js`, `compileall` and `git diff --check`: clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
First step of making the farming analyzer the source of truth for farm spots. This PR pins the analyzer, runs it in the background from Sera's live stats, and adds a dashboard Farming tab with the objective toggle. Autoplay doesn't follow it yet: the follow-up PR switches autoplay to always farm the selected objective's #1 and deletes the hard-coded tiers and
farm_spots.py.Locked inputs
dependencies.lock.jsongains two archive inputs. They use the same fail-closed path as content: digest-pinned HTTPS download, member, size and path limits, required paths, a tree digest in the bundle marker, and a read-only cache generation.farming_analyzer:atrinik/toolsv3.8.0(c624e500),atrinik-tools-farming-analyzer-3.8.0.tar.gz,sha256:3adcce51…, MIT. This is the deterministic asset added in feat(release): publish the farming analyzer as a release asset tools#32; the published bytes match a local rebuild of the tag. It unpacks toanalyzer/.classic_server:atrinik/classicv5.99.0(adcab310, the release MAIN runs),atrinik-classic-server-5.99.0.tar.gz,sha256:ea3fd518…, GPL-2.0-or-later. The analyzer readssrc/server/exp.candskill_util.cfrom it as text. Nothing from it is compiled, linked, executed or distributed. It unpacks toclassic-server/.compatibility.pyvalidates both inputs through one shared_validate_archive_spec, which content now uses too._release_specsincludes them, sopreflightverifies their tags, commits and asset digests on GitHub.install_bundleandinspect_bundleextract and verify them, anddoctorgains afarming-analyzercheck. For air-gapped installs,dependenciesalso accepts--analyzer-archiveand--server-archivealongside--source-archiveand--runtime-archive.THIRD_PARTY_NOTICES.md,PROVENANCE.md, the README andAGENTS.mdrecord the inputs and the out-of-process boundary.Background analyzer (
farm_analyzer.py)combat_profile()reads the killing weapon school (from the equipped weapon's required skill) and its level, plus the player doll: DAM, WC, weapon speed, character level, max HP, speed, AC and protections. These map to the analyzer's server-formula melee options (--melee-damage,--weapon-class,--weapon-speed,--melee-attack slash=100,--player-ac,--player-protection TYPE=PERCENT, …). Only melee weapon schools are simulated for now; other loadouts reportunsupported.FarmAnalyzerowns at most one analyzer process:nice -n 10 python -E -swith the cached analyzer onsys.path,--content-rootand--server-rootfrom the bundle, and--ranking all --top 10 --json. One run ranks every objective, so switching objective never needs a new run.webandautoplaymodes, the CLI builds the analyzer from the installed bundle and polls it every 30 s while the character is in game.Dashboard
farm_objectivein the character state record) through the newfarm_objectiveaction, which rejects unknown objectives.Live analyzer check
With Sera's real stats (slash weapons 22, DAM 44, WC 31, 2.25 s, HP 188, AC 37, slash 49 / pierce 48 / impact 43 / cleave 54 / acid 12), a run through the service took 11.0 s. The event loop kept ticking throughout. The #1 picks:
Two things to act on before autoplay follows these picks:
Validation
weapon_magicbecomingweaponmagicand unsupported loadouts;farming_analysisslice, thefarm_objectiveaction and persistence, and the new tab.test_compatibility: 19 OK, with fixtures and checks extended to both new inputs (validation failures, extraction, marker identities, doctor).dependenciesdownloaded and verified both new artifacts;doctorpassed all five checks, includingfarming-analyzer;preflightagainst GitHub passed all seven.node --check web_static/app.js,compileallandgit diff --check: clean.🤖 Generated with Claude Code