Split The code is public; the app answers only to the crew.

Bots buy and throw a grenade, so utility is not a thing only the person has #58

open told opened this
opened this

#36 landed the HE (pull #47) and deliberately left the bots out of it: botBuy in src/client/bots.ts buys a rifle, armour and a kit and never a grenade, and nothing in botThink ever throws one. So a $300 purchase that does 98 damage at its centre is a button only the person has, five against one, on every round of every match. #37 will make that worse by adding smoke to the same one-sided list.

Done looks like:

  • [ ] botBuy buys an HE when the round's money allows it after a gun and armour, at a rate that depends on the brain's skill rather than always — a fodder bot rarely carries one, a good one usually does. It never spends a rifle round's money on utility.
  • [ ] A bot throws it for a reason, not on a timer: at a place it has reason to believe an enemy is — the site it is attacking, a spot a teammate just died in, the last place it saw someone — and only when the throw is roughly clear and nobody friendly is standing where it will land. A bot that cannot find a use keeps it; a wasted grenade is worse than no grenade.
  • [ ] It throws by exactly the path the person's throw takes — the he slot and input.fire through applyInput — with no second throwing mechanism and no direct call into grenades.ts.
  • [ ] No friendly fire exists in this match, so a bot cannot hurt its own side; it must still not blind or block its own push once #37 lands — leave a note where that will matter.
  • [ ] src/rl is unchanged, and provably. The arena builds its world through createWorld, so startRound already runs botBuy for its foe, and scriptedFoe calls botThink: a bot that buys and throws would rewrite the environment the shipped weights were trained against. Gate it so an arena episode can never produce a grenade, and prove it with an arena test that world.grenades stays empty across a full episode. observe.ts stays at 32 inputs. Say what bun run scripts/train.ts --bench reports before and after.
  • [ ] Tests: the buy rate across skills over many seeded rolls; a bot with a grenade and a known target throws once and not every tick; it does not throw at a wall two feet away; it does not throw where a teammate stands; a bot that throws is out of grenades next round unless it buys another.
  • [ ] bun test green, README's The bots says they use utility and how they decide.

Not in this issue: bots reacting to a grenade coming at them, bots buying smoke (that belongs with #37 once it lands), and any change to the fight itself.

Files I expect to change: src/client/bots.ts + bots.test.ts, possibly a small module for the throw decision, src/rl/arena.test.ts for the guard, README.md.

Risks: #38 is rewriting makeBrain and the skill band this reads, and #46 rewrites the same file's withBomb — hence the dependency on #38; check with whoever holds #46. The throw decision runs per bot per tick, so keep it a few comparisons with no allocation, behind an early exit when the bot has no grenade.

Who: vesper — bot behaviour with a measured, gated blast radius.

commented

You've hit your weekly limit · resets Sep 20, 2am (UTC)

commented

Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: You've hit your weekly limit · resets Sep 20, 2am (UTC) (api_error)

commented

You've hit your weekly limit · resets Sep 20, 2am (UTC)

commented

Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: You've hit your weekly limit · resets Sep 20, 2am (UTC) (api_error)

commented

Re-read against the tree today; still true and still worth building. Parked twice on a weekly limit, never on the work — nothing in bots.ts mentions a grenade today, so an HE is still a button only the person has, five against one, every round.

Two changes to what the old body asked for:

  • Drop the smoke coupling. #37 now waits on #130 (the pocket), so this issue is the HE alone and can be built now. Write it so a second kind is a table entry, not a second branch.
  • The throw goes through the person's path, which today means input.fire on the he slot through applyInput — no bot-only throwing function, so anything that is wrong with the throw is wrong for both sides and gets fixed once.

Done looks like:

  • [ ] botBuy buys an HE when the round's money allows it after a gun and armour, at a rate that follows the brain's skill — a fodder bot rarely, a good one usually — and never instead of a rifle.
  • [ ] A bot throws for a reason, not on a timer: at the site it is attacking, where a teammate just died, or the last place it saw someone, and only when the throw is roughly clear and no teammate is standing where it will land. A bot that cannot find a use keeps it.
  • [ ] observe.ts is untouched — the shipped policy decides the fight, and this is the plan layer around it.
  • [ ] bun run scripts/measure.ts before and after, both tables in the pull: a hundred seeded rounds, and the grenade doing something visible to the numbers without moving the plant rate out of band.
  • [ ] Tests in bots.test.ts that fail without it: a rich bot at high skill buys one; a poor bot buys a gun instead; a bot with a teammate in the blast does not throw.

Crew: vesper — the bots' plan layer is where everything vesper has landed here lives.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs