Public: anyone can read this; the crew can change it.

forked from trevato/cs · proposes

bot spray control is pretty mid #192

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

Pushed. The full suite (856 tests) passes, the app boots and `/` answers in 12 ms.

shipped production is serving it deploy ae07c2d

opened this

Pushed. The full suite (856 tests) passes, the app boots and / answers in 12 ms.

---

The bots' idea of spray control was to point at the floor and let the recoil walk the burst up a body: measured over 120 duels with the old weights, the crosshair sat five to seven degrees below the chest for the whole magazine, the first round of a burst hit 7% of the time and the burst as a whole hit 22%. That is why this is not just a pull bolted onto the old policy — hands that pull down under a head that already aims low only miss lower, and I measured that first (24 wins where the old bots got 33).

So it is two halves. src/client/spray.ts is what a pair of hands does about the pattern it just made: a grip, the share of the pattern they cancel (0.22 for fodder up to 0.9 for the best hands in the game, never 1), and a rate, how fast that pull catches up with the climb, both on the same skill ladder as the turn rate, the wobble and the reaction. The pull is on the view and nowhere else, so the bullets that leave the barrel are the ones a person pulling down would have sent; a flashed bot holds none of it; and a burst that ends gives the whole pull back, so nothing of it outlives the spray. RECOIL_SHARE moved out of shoot into weapons.ts so the shot and the pull cannot disagree about how much of the pattern reaches the bullet. The other half is the aim: the arena now gives its learner those same hands, hands it the grip as the 33rd number it observes, and pays the shaped reward on muzzleError — the angle between the line to the enemy's chest and where the next round would actually land — instead of on yaw alone, which is what had left pitch to the damage term and taught the floor-aiming. Retrained from scratch: 1,000 updates, 8.2M ticks, 12.5 minutes, 71% won on de_forge against the scripted baseline's 42%, and 73% won with 10% drawn on the 24 maps it never trained on (baseline 49%/19%, and the old weights 69%/12%). Spray accuracy 22% → 51%, mean burst 9.3 rounds → 3.8, and the same game-bots-versus-baseline duels go from 33 wins to 66.

What to look at in the preview: stand at the end of long A and hold an angle — the bots now walk their crosshair down through a spray instead of hosing over your head, and a low-skill bot still sprays off into the ceiling, which is the ladder working. src/client/spray.test.ts is the claim measured on the real bullets (ninety AK rounds at a standing body: 339 damage uncontrolled, 3,639 with the best hands), and src/rl/arena.test.ts pins the new shaping. What I chose not to do: the scripted brain does not ride the pattern — it is the baseline the policy is measured against and a baseline that moves measures nothing, so its arena digest is untouched — and I left trigger discipline to the policy, which picked shorter bursts on its own. The ten-bot round digest is re-pinned deliberately: the first nine seconds hash the same to the character, and every second after the bots have someone to shoot at is different.

🤖 Generated with Claude Code

Closes #190

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs