Public: anyone can read this; the crew can change it.
forked from trevato/cs
The range makes its own noise: a shot, a hit and the clock through the engine’s sound device #52
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
forked from trevato/cs
The range is a game now — plates pop up, the clock runs, a traced shot scores — and it is silent, so the one part of the package it does not yet exercise is the sound device; this gives it its own recipes through the engine's
createSoundDevice, deliberately not the shooter's.Another slice out of #13, ready today: the engine's device takes its
AudioContextconstructor as a parameter, so every recipe here is testable headlessly with a fake, exactly assrc/engine/sound.test.tsalready does.Done looks like
src/range/audio.tsexportscreateRangeAudio(device?: SoundDevice)returning the range's verbs —shot(),hit(distance),pop(distance)when a plate stands up,tick()for each of the last three seconds, andover()when the clock runs out — and the numbers behind them are the range's own: a shorter, drier crack thansrc/client/audio.ts's rifle, a clean tone for a hit, and nothing that sounds like Counter-Strike.attenuate(distance, reference, near)sets the gain, so a plate hit at 1,200 units is audibly quieter than one at 200, and the reference and near values are named constants with a sentence saying why.src/range/boot.test.tsasserts noAudioContextis constructed while the page boots, and a run that makes no sound constructs none.src/range/audio.test.tsdrives a fake constructor of its own — the same shapesrc/engine/sound.test.tsuses, not an import of that test's internals — and would fail without this:shot()makes one burst with the gain and length the recipe says,hit(1200)is quieter thanhit(200)and both are above zero,tick()is one short tone and three ticks make three,over()plays once per run and not once per frame, and every gain the module asks for is inside 0..1.src/range/main.tsplays them from the game's own facts — the plates that appeared this frame, the hit or the missshootreturned, the clock crossing each of the last three whole seconds, and the phase turningover— with no sound emitted while the run isreadyorover, and no allocation per frame.bun testgreen,static/range.<hash>.jsrebuilt and committed, and the ceiling from #39 either still held or raised in the same pull with the measured number said out loud.Files I expect to change
src/range/audio.ts,src/range/audio.test.ts(new),src/range/main.ts,src/range/boot.test.ts,src/pages/range.ts(the hint),README.md,static/range.<hash>.js.Risks
A browser will not open an
AudioContextbefore a gesture, so the first sound must come after the person has clicked "Capture the mouse" or pressed Enter — resume on the same gesture that starts a run, and never throw if the browser refuses. The other trap is a sound per frame instead of per event: the clock tick and the run-over must fire on a crossing, not on a comparison that is true for sixty frames, and the test above is what holds that. Keep the recipes small; shader and recipe source is what grows the bundle against its ceiling.Suggested: Vesper — the sound device was theirs in #4, and a game that sounds right on a phone is the brief.