fix/bot-rotation-and-pk-idle #216

Merged
sickday merged 3 commits from fix/bot-rotation-and-pk-idle into main 2026-07-23 14:06:29 +00:00
Owner
No description provided.
Three field reports (bots idling at fishing spots in full battle gear,
PKers trash-talking in the wild without ever fighting, staff-wielding
bots piling up at the river by Barbarian Village), four root causes:

- The PKer chain's earn leg was a bare `{FishAndBank, %{target: 2}}`:
  no `:relocate`/`:equipment`, so the transition hook never fired — no
  teleport, no gear swap, PK inventory kept. The bot then walked to the
  nearest spot with any catchable fish because `find_fishable_spot`
  ignored `tool_id` — from Edgeville that's the Barbarian Village fly
  spot, where the net-carrying bot's "Lure" is refused on every cast.
  The `:fishing` stall counter could never trip either: `find_npc`
  zeroes `ticks` on each interact, so the fishing→find_npc retry bounce
  pinned it at <=1 and the bot froze at the waterline forever (the
  river pile-up from the screenshots, reproduced at the exact tile).

  New `Rotation.earn_task/0` builds the earn leg from a net fisher
  spread entry (level-1 fishing works for any rolled Fishing level)
  with relocate/outfit/target, filtered to gate-free bank->spot legs —
  the transition banks the whole pack, so a broke retiree wedges at the
  Al Kharid toll gate if routed through it. `entry_casts` deposits the
  backpack on teleporting transitions; the PK config gains `:relocate`
  so the loop restart teleports back to its restock bank. FishAndBank
  gains the tool gate and a `start_attempts` counter that survives the
  find_npc bounce, so a spot that refuses to start rotates instead of
  freezing.

- `killed_target?` counted any cleared combat target as a kill while
  the victim stood alive in the MovementAuthority — every dropped
  fight (flee, single-combat lock) fired kill trash-talk and credited
  phantom `kill_reward` coins, so `coins_earned` outran spend and
  `budget_exhausted?` never rotated the bot out. Kills now confirm via
  the shared `CombatBrain.confirmed_kill?/1` (MA dead-or-gone only);
  ScavengeAndRush had the same bug.

- An aggressive wilderness NPC poking a PKer holds `last_attacker` at
  the NPC, so every player engage was dropped by the attacker-busy
  single-combat gate — an endless engage/fake-kill chatter loop over a
  fight that could never start. Roaming now holds while NPC-engaged
  (server retaliation clears the skeleton) and fighting bails out
  instead of running the player-fight brain against an NPC.

- The `head_to_bank` legs in PkAndRestock and LootAndAlch re-issue
  walks forever with no give-up; a bot at an unreachable pocket stood
  for good. Eight fully-stationary goal ticks on a bank leg now
  recover to the nearest hub.

Also swept up while in there:

- `{:bot_deposit_equipment_slot, ...}` had no handle_cast clause —
  RunecraftAndBank's tiara return crashed the bot outright. Added the
  handler + `BotHandlers.deposit_equipment_slot/3` (economy deposit,
  slot/id-matched, no-op otherwise). Its tiara equip also used
  `bot_equip_set`, which replaces the whole loadout — the runecrafter
  ended up wearing nothing but a tiara; now `bot_equip_batch`.

- `Locations.match_route` accepted tolerance-matched slices that end
  no closer to the destination than the bot already stands — a
  15-tile Draynor bank->spot hop matched a passing Draynor->Barbarian
  long-haul route and marched the bot 100 tiles north first. A slice
  must now improve on the current distance.

Verified live: a budget-exhausted mager retires at the bank, teleports
to a net hub, swaps into casual clothes, banks its kit leftovers, and
net-fishes; two equal-level PKers still fight to a finish.
A blocked placement anchor fell straight through every fallback onto
the blocked tile itself: reachable_tiles/2's flood cannot start from a
non-occupiable anchor and returns [], and find_walkable_tile /
free_spawn_tile both answered that with the raw anchor — planting the
bot on water or inside a wall, on a tile no walk can ever leave (and
::botfix, which routes through find_walkable_tile, kept re-choosing the
same blocked tile instead of rescuing it). Bot teleports and
reset_position never validated their destination at all, so one bad
tile in data or a hand-typed coord did the same.

New Collision.Manager.nearest_occupiable/2 ring-scans outward for the
closest standable tile (no connectivity requirement, so it still finds
the shore from mid-river); find_walkable_tile, the ::botgen spawn
scatter, and the bot teleport/reset paths all snap through it. A good
destination passes through untouched; an unloaded region returns the
anchor unchanged.

Verified live: a teleport aimed at mid-river (3113,3431) by Barbarian
Village lands on the bank at (3115,3428).
fix: ditch leap lands on standable ground, not the trench row
All checks were successful
ci / test (pull_request) Successful in 2m37s
191dcc3085
Operator report: three bots boxed in at (3132..3134, 3521) — ON the
ditch row, outside the wilderness, unable to move.

The crossing ForceMove is collision-blind (it has to be, to carry the
avatar over the trench), so the landing tile must be chosen standable —
and the naive trajectory got it wrong twice over. The southbound
landing ditch_y - 1 = 3521 is the ditch loc's own clipped southern row
(the loc sits at y 3521..3522, not 3522..3523), so EVERY south crosser
landed on a blocked tile; it went unnoticed because the next walk step
off it usually had an open neighbour at y 3520. Where the ditch meets
the wilderness river (x 3123..3134) that pocket is water in both
directions — rows 3518..3520 south and 3523..3527 north are blocked for
several columns — so a bot crossing there landed with every neighbour
blocked and stood forever.

New landing_tile/4 scans the same column a few tiles onward first
(prefer straight across, just past any clipped row), then slides up to
8 columns along the row to the nearest crossable one; nothing nearby
standable (or bare test env) falls back to the naive tile. Covers the
player Cross click and the bot crossing alike.

Live-verified at the junction: south from (3133,3525) lands (3133,3518),
south from (3128,3526) lands (3128,3519), north from (3128,3520) lands
(3130,3527) — all standable. Straight-across columns are unchanged
except landing one tile beyond the trench row.
sickday force-pushed fix/bot-rotation-and-pk-idle from 191dcc3085
All checks were successful
ci / test (pull_request) Successful in 2m37s
to 48e56e555e
All checks were successful
ci / test (pull_request) Successful in 2m35s
2026-07-23 14:00:39 +00:00
Compare
sickday referenced this pull request from a commit 2026-07-23 14:06:31 +00:00
Sign in to join this conversation.
No description provided.