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

Radio: three calls the person can make, and four teammates who actually go #63

Closed opened this has it
opened this

The person has no say over their own side. brain.site = siteFor(world.plan, bot.team, slotOf(world, bot)) (src/client/bots.ts:375) reads a plan rolled from the seed and the round number, so four teammates commit to a site before the freeze time ends and nothing a person does can move them. You can watch your whole team walk to B while you stand in A with the bomb, every round, forever. In CS that is what the radio is for.

Done looks like:

  • [ ] Three calls, and no more: go A, go B, and hold (stay and defend where you are). One key opens a small radio panel — the same DOM-overlay pattern the buy menu uses, so a keyboard and a thumb both reach it — with three big buttons, and it closes on the call or on Escape.
  • [ ] A call is plain data on the world (the side that called, what was called, when), and the side's plan reader honours it: siteFor — or a thin layer over it — returns the called site for the person's team while a call is live, and falls back to the rolled plan when it expires or the round ends. Nothing deep inside bots.ts learns the word "radio".
  • [ ] Only the person's own side hears it, only one call is live at a time, a call expires after a sensible few seconds of the round rather than lasting forever, and a new round starts with none.
  • [ ] Bots already on their way re-path on the next tick through the goal they already choose; a bot carrying the bomb obeys "go A" exactly as it obeys the plan, and "hold" stops a push without freezing anyone in the open.
  • [ ] The call goes on the HUD's message line — world.messages and say() already exist and the HUD draws the last one — as "You: go A", so the person can see that the team heard it.
  • [ ] Tests: a call changes the site the plan hands the person's side and not the other side's; it expires; it is cleared by startRound; a bot carrying the bomb follows it; two calls in a row leave only the second live; and siteFor's behaviour with no call is byte-identical to today's.
  • [ ] bun test green, README's Playing names the key and says what the three calls do.

Not in this issue: voices or audio for the calls, bots calling anything themselves, a chat box, and any change to how the plan is rolled when nobody calls.

Files I expect to change: src/client/plan.ts (the override layer) + plan.test.ts, src/client/world.ts (the live call), bots.ts only where it reads the plan, main.ts, input.ts, src/pages/game.ts, README.md.

Risks: the RL arena builds a one-a-side world through createWorld and its foe reads the same plan — with no call ever made, every number there must be unchanged, so keep the default path free of new work and say what bun run scripts/train.ts --bench reports. bots.ts is contended: #38 is in hand and #46 and #58 are queued behind it, which is why this waits on #38 and why the override belongs in plan.ts rather than in the goal code.

Who: vesper — the plan, the bots that read it and the arena's numbers.

commented

API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN)

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: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error)

commented

Split, as the park asked for. The park reason was an API outage rather than anything wrong with the issue, but it is too big for one run either way — it asked for the plan override, the expiry, the bots, a new overlay, the touch pad and the README together. It is now #103 (a live call on the world, three keys, the plan override, the bots that obey it, the message line, the tests) and #104 (the panel a thumb can reach, the pad button and the README), with #104 waiting on #103. Closing this one; the work is in those two.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs