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

Teammates who call it out: what a bot sees, said once, to its own side #164

Closed opened this
Closed without merging

Four teammates who had been walking around in silence now say what they can see, on the message line the HUD already draws.

stopped closed without shipping deploy 10c9a72

opened this

Four teammates who had been walking around in silence now say what they can see, on the message line the HUD already draws.

The vocabulary is the map's. MapDef gained places — the layout's own named areas, labelled once when the map is built (placeLabel: "a site" is said A site, "ct mid" is CT mid) — and placeAt(map, pos) says which one a point stands in, last-painted-first so it agrees with the cells buildGrid actually painted. There is no table of coordinates: a callout can only ever name a room the rock was carved into, and map.test.ts walks every walkable cell of both maps to prove every one of them has a name.

callout.ts is the rule — four things a bot may say (a sighting, a noise, a defuse, a last magazine), the words each is said in, and three gaps. SIDE_GAP 4s because the HUD holds a line for four (MESSAGE_FADE) and a side that talks faster overwrites itself unread; SPEAKER_GAP 6s so no one voice can hold the feed; REPEAT_GAP 12s so five teammates walking into the same angle say "enemy — mid" once between them. On top of the gaps a sighting is said on contact and not for every tick of one, so a ninety-second standoff down one corridor is a single line, and a round where nothing happens says nothing. A defuse is one line an attempt (REPEAT_GAP outlasts the longest defuse) and a bot says it is down to its last ten rounds once a gun, latched on the brain.

world.ts's callout is the gate, ordered by price: the person's own side → a round actually being played (never over the round result the HUD is holding) → two numbers off the rate limit → and only then the place and the string. So a bot with an enemy in its sights and nothing new to say costs two comparisons and allocates nothing. The enemy's bots never reach the first gate, which is the point: a callout is a teammate telling you what they can see, never what the other side knows. scripts/measure.ts prints the identical 87-round table in 76.2s against 76.6s before on this machine, and train.ts --bench holds at 13k steps/s either way — the simulation itself is bit-for-bit unchanged, since nothing here draws on world.random or a brain's.

What to look at in the preview: play a round and watch the line — Krait: enemy — long A, Pike: noise — mid (worded so it can never be read as a sighting — it is a footstep through a wall and the place is reported's guess), Draco: defusing — A site. A round restart clears the chatter and drops the callouts from the queue while leaving the last round's result on screen, which is why messages grew an optional by.

What I left out: the person's own side is the only one with a Chatter record, because it is the only one that can ever speak — the other side's state would be a structure nothing reads. And scriptedFight (the arena's baseline opponent) says nothing; it is a measuring stick, not a teammate.

🤖 Generated with Claude Code

Closes #111

commented

Parked by the crew: the check failed and the decider saw no point in another try

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs