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

forked from trevato/cs

The range hears the lane: the second game picks up the engine pan the shooter got #288

Merged opened this

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

Merged

`src/range/audio.ts` passed no `pan` anywhere, so the second game played a lane whose plates are spread ±420 across it entirely down the middle. The two sounds that happen out in the lane now take where they happened and the ear that hears them — a plate's centre for the knock, the point the bullet stopped for the hit tone, `view.eye` and `view.yaw` for the ear — and go through the same `panOf` th…

shipped production is serving it deploy ae07c2d

opened this

src/range/audio.ts passed no pan anywhere, so the second game played a lane whose plates are spread ±420 across it entirely down the middle. The two sounds that happen out in the lane now take where they happened and the ear that hears them — a plate's centre for the knock, the point the bullet stopped for the hit tone, view.eye and view.yaw for the ear — and go through the same panOf the shooter got in #217. The three that are the range's own voice — your crack, the clock's last three ticks and the tone that ends a run — are handed no ear at all: the device builds them no panner and they stay centre wherever you look.

The softening is the range's own rather than the shooter's, and it is one number with its paragraph: LANE_PAN is 0.7. The widest raw pan this game can produce is a tracking plate at its ±560 escape and 360 deep, about 0.84, and the pop-up drill's ±420 at 320 deep is 0.79 — nothing at a range is beside you, so those become 0.59 and 0.56, a firm side with the other speaker still in it. The shooter is untouched and still passes panOf straight through, because a body walking past its ear really is beside you.

Worth looking at: centreOf in src/range/targets.ts, which moves the "where is this plate" arithmetic that step had inline and scene.ts had again into one place; and the tests, which are the behaviour. src/range/audio.test.ts reads the panner off its fake context — a plate on the left comes back negative, the same plate mirrored positive, one straight down the lane zero, a plate sampled across the lane monotonic left to right, turning onto a plate centres it, and a context with no createStereoPanner plays the whole lane centred with exactly the gains it always had. src/range/boot.test.ts proves it through the whole page without knowing the seed: the drills cannot stand a plate more than 57° off the lane, so a view turned ninety degrees puts every plate on one ear and half a turn back puts them all on the other, and every voice the range says itself comes back unplaced.

Bundle: 36,059 → 36,351 raw and 15,169 → 15,267 gzipped, both inside the ceiling with 649 and 233 bytes left, so no ceiling moved. bun run test is green (1,247 tests). Two rows of the seam table in src/engine/GUIDE.md changed: "sound recipes" said none yet for a game that has had src/range/audio.ts for days, which is what this issue asked for, and the mover's row beside it still said nobody walks in the range, which #63 made false — I fixed it while the file was open rather than leaving a second lie on the page. The range page's two paragraphs about sound now say the plates are where the stereo is.

🤖 Generated with Claude Code

Closes #221

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs