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

A bomb you can hear: a beep that quickens, a plant, a defuse, an explosion and the click of an empty gun #44

shipped merged opened this has it
opened this

The planted bomb is silent. In a defusal game the beep is the information — it says which site, how far away and how little time is left — and here a CT can stand ten feet from a live bomb and hear nothing. The same silence covers the plant, the defuse, the detonation, the start of the round and a trigger pulled on an empty magazine.

Where it stands. Audio in src/client/audio.ts is shot, step, hit, pain and beep; beep is used in exactly one place, the buy click at main.ts:168. The { kind: "sound", name } effect declared at world.ts:70 is pushed by one caller, footsteps, with name: "step", and feelEffects in main.ts routes exactly that one name. Panning and distance are already solved by ears.ts.

Done looks like:

  • [ ] A new src/client/cues.ts owning one concept — when a bomb beeps: given the seconds left on the bomb and when it last beeped, whether it beeps now and at what pitch. The interval quickens as the fuse runs down (roughly a second apart at 40 s, a few a second at the end) and the pitch rises with it. Pure arithmetic: no audio, no world, no DOM.
  • [ ] world.ts pushes { kind: "sound", name: "beep", pos: bomb.pos } on that cadence while the phase is planted, at the bomb's position, so ears pans it and a CT can walk to the site by sound alone.
  • [ ] The other four moments push one sound each, at the position they happen: plant when the plant completes, defuse when it completes, explode on bomb_timeout, and empty when shoot refuses for an empty magazine — once per press, not once per tick.
  • [ ] audio.ts grows one way to play a named world sound, panned and attenuated through ears like shot and step already are, with a tone per name. beep(pitch) stays what it is: the UI click. Mute and volume keep working through the one master gain.
  • [ ] feelEffects routes sounds by name instead of matching "step", and the earshot rule is per name: a footstep stays short-range (FOOTSTEP_EARSHOT), a bomb beep and an explosion carry across the map.
  • [ ] Tests: cues.test.ts — the first beep lands right after the plant, intervals are monotonically shorter as the fuse shortens, no beep when nothing is planted, and the rate is bounded however small dt is. world.test.ts — a planted bomb pushes beeps on that cadence and stops on a defuse; the detonation pushes exactly one explode; a dry trigger pushes one empty per press.
  • [ ] bun test green, README's What is real says the bomb beeps and what the other cues are.

Not in this issue: music, voices or radio calls, a beep the HUD draws, and the bomb's damage model — BOMB_RADIUS killing everything within 1000 units with no falloff is a separate argument.

Files I expect to change: src/client/cues.ts + cues.test.ts (new), src/client/audio.ts, world.ts, main.ts, world.test.ts, README.md.

Risks: src/rl/arena.ts steps this same world thousands of times a second per core, so the cadence must be a couple of pushes a second at worst and must cost nothing when no bomb is down — say what bun run scripts/train.ts --bench reports before and after. Do not touch observe.ts: the shipped weights were trained on those 32 inputs and the card on the page quotes their numbers. world.ts is also being edited by #36 and #39; this change lives in updateBomb, shoot's empty branch and the bomb_timeout event, so keep out of the middle of shoot.

Who: vesper — this is the simulation's effect stream and the synthesiser behind it.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs