Point a gathering bot, and state the gather and bank rules once #139

Merged
sickday merged 3 commits from feat/bot-targets into main 2026-08-06 16:03:21 +00:00
Owner

Three commits: a feature that had been sitting unpushed, the bug it uncovered,
and the test that needed headroom once the world got bigger.

Point a chopper or a miner at one species or ore

::botgen [count] [kind] [target] [--here] [--xp <rate>], tokens still
order-independent. A gathering kind takes a :keychopper yew,
miner coal — and Bot.Kinds.spec/4 raises the seed level to what that
target demands, picking the tool from the raised level and never falling below
the default, so chopper oak changes nothing.

That level is the whole point. Every chopper seeded at Woodcutting 41 and
Bot.Sites.tree_sites/2 filters nodes by level, so maple (45) and yew (60)
were invisible to every chopper ever spawned — 20 maple sites and 34 yew ones
that the site table held and no bot could reach. The table was a superset and
the capability was a subset.

Targets are read off the skills' own cache-scanned tables through
Bot.Seed.targets/1, at the lowest level a target's rows demand, so a species
the scan starts finding is a target an operator can name the same day. A target
is recognised against every targeted kind before the kind is known — tokens
are order-independent — and accepted only if the kind settled on takes it, so
::botgen 1 miner yew answers with the miner's list instead of swallowing a
typo.

Bot.Goals.GatherAndBank needed no change; it already read
Map.get(config, :key, :any).

State the gather verbs and the bank test once, not twice

Bot.Sites wrote its own version of two rules the engine already owned, and
both restatements were narrower than the original.

The chop verb. The tick accepts five spellings; the site table scanned for
an option starting with chop. The arctic pine's option is Cut down and
both redwoods' is Cut, so 61 placements a player could fell that day were
dropped at the rows stage — before placements were folded, and long before a
bank was looked for. The symptom was two species with no site anywhere, which
reads exactly like content the cache does not carry, and that is what had been
written down about them.

The bank test. Only the exact verb Bank counted, so a bank chest was
not a bank. The chest is the only bank on Neitiznot and the only bank in the
Woodcutting Guild — which is where "the arctic pine's nearest bank is 216 tiles
away" came from. It is 3.

So Contract.Gather holds the verbs and Contract.Bank.booth_slot/2 holds the
bank test, and World.Player.Advance, World.Content.Bank and Bot.Sites all
ask them. A chest needs its name as well as its verb, since Use is also a
crevice, a viewing orb and every poll booth; that is not the rule against
recovering an id by name, because nothing here looks an id up, and two locs
sharing the name is the rule working rather than failing. 10083, a
Bank booth whose only action is Use, stays out — nothing in the game banks
there.

What it is worth

Derived against a real cache, whole world, on this base:

before after
banks 52 74
tree sites 621 803
rock sites 45 72
fishing grounds 20 33

267 tree sites and 38 rock sites now bank at a chest. Mining gained 60% more
sites and fishing 65%
from a change made for Woodcutting — every skill reads
the same bank table. Arctic pine went from no site in the world to 13, each
banking at the chest three tiles away.

A player is affected too, not only a bot: clicking a bank chest did nothing at
all before this, with no message, which is indistinguishable from a click that
missed.

Still nowhere to work

Teak (#135) and redwood (#136) still derive no site, and ::botgen still says
so rather than refusing. Teak is the genuine bank-pairing drop at 108 tiles and
wants a bankless drop loop; redwood stands on planes 1 and 2 with its chest on
plane 0, and Bot.Travel cannot change plane. The obvious cheaper explanation
for redwood — that the bridge-tile indexing fix in 17156e5 had put it a
storey high — was tested on top of that fix and is wrong: the placements are
unchanged. Bank deposit boxes are #137.

Checks

mix revenant.ci --gates passes bar the two Dialyzer guard_fails already
filed as #131, unchanged in count and location with this branch and without it.
Full suite green.

Also reformats test/support/login_packet.ex, which was failing
--check-formatted on a clean tree — the other half of #131.

One test needed headroom, and it lies about why

Bot.GatherWorldTest waited 90 seconds for a chopper to chop one log and bank
it. Adding 182 sites moved the closest-banked site it stands its bot on, and
standing a bot on a site does not oblige it to work that one — choose/2 rolls
between the nearest few — so the trip is whichever came up plus its own bank
leg. Alone the file runs in 48 seconds; inside the full suite, sharing a 600ms
tick with every other world test, it has been measured past ninety.

Measured rather than assumed: passes alone, passes across the whole bot
directory, passes a full suite on seed 7, fails on seed 602971. At 150 seconds
it passes on 602971 too. The failure mode is worth knowing because it reads as
a broken deposit — the assertion that fires is no logs ever reached the bank.

The only other failures on that seed are the fourteen that come from running a
second suite against the same test database, which is a known fixture issue and
not this branch's.

Three commits: a feature that had been sitting unpushed, the bug it uncovered, and the test that needed headroom once the world got bigger. ## Point a chopper or a miner at one species or ore `::botgen [count] [kind] [target] [--here] [--xp <rate>]`, tokens still order-independent. A gathering kind takes a `:key` — `chopper yew`, `miner coal` — and `Bot.Kinds.spec/4` raises the **seed level** to what that target demands, picking the tool from the raised level and never falling below the default, so `chopper oak` changes nothing. That level is the whole point. Every chopper seeded at Woodcutting 41 and `Bot.Sites.tree_sites/2` filters nodes by level, so maple (45) and yew (60) were invisible to every chopper ever spawned — 20 maple sites and 34 yew ones that the site table held and no bot could reach. The table was a superset and the capability was a subset. Targets are read off the skills' own cache-scanned tables through `Bot.Seed.targets/1`, at the lowest level a target's rows demand, so a species the scan starts finding is a target an operator can name the same day. A target is recognised against *every* targeted kind before the kind is known — tokens are order-independent — and accepted only if the kind settled on takes it, so `::botgen 1 miner yew` answers with the miner's list instead of swallowing a typo. `Bot.Goals.GatherAndBank` needed no change; it already read `Map.get(config, :key, :any)`. ## State the gather verbs and the bank test once, not twice `Bot.Sites` wrote its own version of two rules the engine already owned, and both restatements were narrower than the original. **The chop verb.** The tick accepts five spellings; the site table scanned for an option *starting with* `chop`. The arctic pine's option is `Cut down` and both redwoods' is `Cut`, so 61 placements a player could fell that day were dropped at the rows stage — before placements were folded, and long before a bank was looked for. The symptom was two species with no site anywhere, which reads exactly like content the cache does not carry, and that is what had been written down about them. **The bank test.** Only the exact verb `Bank` counted, so a **bank chest** was not a bank. The chest is the only bank on Neitiznot and the only bank in the Woodcutting Guild — which is where "the arctic pine's nearest bank is 216 tiles away" came from. It is 3. So `Contract.Gather` holds the verbs and `Contract.Bank.booth_slot/2` holds the bank test, and `World.Player.Advance`, `World.Content.Bank` and `Bot.Sites` all ask them. A chest needs its **name as well as its verb**, since `Use` is also a crevice, a viewing orb and every poll booth; that is not the rule against recovering an id by name, because nothing here looks an id up, and two locs sharing the name is the rule working rather than failing. `10083`, a `Bank booth` whose only action is `Use`, stays out — nothing in the game banks there. ### What it is worth Derived against a real cache, whole world, on this base: | | before | after | |---|---|---| | banks | 52 | **74** | | tree sites | 621 | **803** | | rock sites | 45 | **72** | | fishing grounds | 20 | **33** | 267 tree sites and 38 rock sites now bank at a chest. **Mining gained 60% more sites and fishing 65%** from a change made for Woodcutting — every skill reads the same bank table. Arctic pine went from no site in the world to 13, each banking at the chest three tiles away. A player is affected too, not only a bot: clicking a bank chest did nothing at all before this, with no message, which is indistinguishable from a click that missed. ### Still nowhere to work Teak (#135) and redwood (#136) still derive no site, and `::botgen` still says so rather than refusing. Teak is the genuine bank-pairing drop at 108 tiles and wants a bankless drop loop; redwood stands on planes 1 and 2 with its chest on plane 0, and `Bot.Travel` cannot change plane. The obvious cheaper explanation for redwood — that the bridge-tile indexing fix in `17156e5` had put it a storey high — was tested on top of that fix and is wrong: the placements are unchanged. Bank deposit boxes are #137. ## Checks `mix revenant.ci --gates` passes bar the two Dialyzer `guard_fail`s already filed as #131, unchanged in count and location with this branch and without it. Full suite green. Also reformats `test/support/login_packet.ex`, which was failing `--check-formatted` on a clean tree — the other half of #131. ### One test needed headroom, and it lies about why `Bot.GatherWorldTest` waited 90 seconds for a chopper to chop one log and bank it. Adding 182 sites moved the closest-banked site it stands its bot on, and standing a bot on a site does not oblige it to work that one — `choose/2` rolls between the nearest few — so the trip is whichever came up plus its own bank leg. Alone the file runs in 48 seconds; inside the full suite, sharing a 600ms tick with every other world test, it has been measured past ninety. Measured rather than assumed: passes alone, passes across the whole bot directory, passes a full suite on seed 7, fails on seed 602971. At 150 seconds it passes on 602971 too. The failure mode is worth knowing because it reads as a broken deposit — the assertion that fires is *no logs ever reached the bank*. The only other failures on that seed are the fourteen that come from running a second suite against the same test database, which is a known fixture issue and not this branch's.
A chopper left alone works whatever site is nearest, and every one seeded
at Woodcutting 41 while `Bot.Sites.tree_sites/2` filters nodes by level —
so 20 maple sites and 34 yew ones were invisible to every chopper ever
spawned. The site table held them; no bot could reach them.

`::botgen [count] [kind] [target]` names one, tokens still
order-independent. `Bot.Seed.targets/1` and `level_for/2` read the species
and ores off the same cache-scanned tables the tools come from, taking the
lowest level a target's rows demand. `Bot.Kinds.spec/4` then computes the
seed level from the merged config and picks the tool from the raised level,
never below the default: pointing at oak changes nothing.

A target is recognised against every targeted kind before the kind is
known, then accepted only if that kind takes it, so `::botgen 1 miner yew`
answers with the miner's list instead of swallowing a typo. Teak, arctic
pine and redwood derive no site at all — the reply warns rather than
refuses, because a pointed fleet with nowhere to work spawns and stands
still forever.
`Bot.Sites` wrote its own version of two rules the engine already owned, and
both restatements were narrower than the original.

The first was the chop verb. The tick accepts five spellings; the site table
scanned for an option *starting with* `chop`, so the arctic pine (`Cut down`)
and both redwoods (`Cut`) were dropped at the rows stage — 61 placements a
player could fell that day, gone before the table had looked for a bank. The
symptom was two species with no site anywhere, which reads exactly like
content the cache does not carry, and that is what had been written down.

The second was the bank. Only the exact verb `Bank` counted, so a bank chest
was not a bank — and the chest is the only bank on Neitiznot and the only one
in the Woodcutting Guild. That is where the arctic pine's "nearest bank 216
tiles away" came from; it is 3.

So `Contract.Gather` holds the verbs and `Contract.Bank.booth_slot/2` holds
the bank test, and `World.Player.Advance`, `World.Content.Bank` and
`Bot.Sites` all ask them. A chest needs its name as well as its verb, since
`Use` is also a crevice and a poll booth — which is not the invariant against
recovering an id by name, because nothing here looks an id up.

Derived against the cache, before and after: banks 49 to 71, tree sites 609
to 791, rock sites 45 to 72, fishing grounds 20 to 33. Arctic pine goes from
no site in the world to 13, each banking three tiles away. Mining and fishing
gained most of that without being touched — every skill reads the same bank
table.

Teak (nearest bank 108) and redwood (planes 1 and 2) still derive nothing,
and `::botgen` still says so. `test/support/login_packet.ex` is reformatted
in passing; it was failing --check-formatted on a clean tree.
test(bot): give the chopper's round trip room for a loaded suite
Some checks failed
ci / gates (pull_request) Failing after 14s
e7032f99ef
`Bot.GatherWorldTest` waited 90 seconds for a chopper to chop one log and
bank it. That is generous alone — the file runs in 48 seconds — and not
generous inside the full suite, where the same trip shares a 600ms tick with
every other world test.

It surfaced now because this branch put 182 more sites in the table, which
moved the closest-banked site the test stands its bot on, and standing a bot
on a site does not oblige it to work that one: `Bot.Sites.choose/2` rolls
between the nearest few, so the trip is whichever of three came up plus its
own bank leg.

Measured rather than assumed: the test passes alone, passes across the whole
bot directory, and passes in a full suite on seed 7 — and fails on seed
602971. With the patience at 150 seconds it passes on 602971 too, which is
the claim this commit makes and the way to falsify it.

The failure mode is worth knowing because it lies: the assertion that fires
is "no logs ever reached the bank", which reads as a broken deposit rather
than a slow one.
sickday force-pushed feat/bot-targets from e7032f99ef
Some checks failed
ci / gates (pull_request) Failing after 14s
to c254f199a4
Some checks failed
ci / gates (pull_request) Failing after 13s
2026-08-06 15:46:47 +00:00
Compare
sickday force-pushed feat/bot-targets from c254f199a4
Some checks failed
ci / gates (pull_request) Failing after 13s
to 6122410591
All checks were successful
ci / gates (pull_request) Successful in 56s
build / image (push) Successful in 30s
ci / gates (push) Successful in 1m5s
2026-08-06 15:58:35 +00:00
Compare
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Revenant/Server!139
No description provided.