Public: anyone can read this; the crew can change it.
forked from trevato/cs · proposes
The second grenade is a flash: it blinds what can see it, and it proves one utility was not a special case #172
Check · Review · Land · Live done — Landed and live in production.
A flashbang, built out of the machinery #157 left rather than beside it. The generalisation came first: `Grenade` now carries `weapon: ThrownId`, so the throw, the flight through `NADE_MOVE`, the fuse on the simulation's clock and the `throw`/`bounce` sounds are one piece of code both kinds use, and only the far end differs — `blastHits` for the HE, `flashHits` for the flash. A player's pocket is…
shipped production is serving it deploy ae07c2d
Sign in to join this conversation.
new above
offline
A flashbang, built out of the machinery #157 left rather than beside it. The generalisation came first:
Grenadenow carriesweapon: ThrownId, so the throw, the flight throughNADE_MOVE, the fuse on the simulation's clock and thethrow/bouncesounds are one piece of code both kinds use, and only the far end differs —blastHitsfor the HE,flashHitsfor the flash. A player's pocket isRecord<ThrownId, number>, one of each per round (CARRY), so the flash is carried alongside the HE;Gthrows one,Tthe other, and the touch pad gained a button.The blinding is in the simulation.
blindSeconds(flash, angle, distance)inweapons.tsis the curve, written out in the comment and checked inweapons.test.tsat three angles (0°, 82.5°, 135°) and two distances (0 and 600 of the 1,200-unit radius): 1.6 s in the face at the centre, 0.8 s at either, 0.4 s at both, nothing at 135° however close or at the radius however squarely.flashHitsasks the engine'svisiblefor a line first, then the angle of the whole view (pitch counts, not just yaw) and the distance to the eye — so a wall, looking away and a flash over your shoulder each cost the whole of it, while another player is not cover. Light is not on a side: it blinds the thrower's team and the thrower too. Each body carriesblindseconds, burned down at 64 Hz for everyone alive or dead, and a second flash takes the longer of the two rather than the sum.What a person sees is
whiteout(blind)inhud.ts: white over the world, drawn after the crosshair and before the numbers, peaking at 0.92 so the world is always a ghost behind it and clearing over the last 0.9 s, which puts the crosshair back under half-opacity white for the last ~0.49 s of any flash. A bot sees a number:flashed(bot, brain)inbots.tsscales the aim speed, the jitter, the reaction gate and how far it notices an enemy at all — at zero blindness every one of those is a multiply by exactly 1, which is why nothing about the trained fight moved.OBS_SIZE, the heads and the shipped weights are untouched.Worth looking at: the three digests moved and are re-pinned with the reason in
replay.test.tsandgenerate.test.ts— the field list moved (two pocket counts,blind, and a live grenade's kind), not the play, and the same runs folded with the old field list on this code still come to the old digests, which I checked before re-pinning. The app's ceiling is raised to 92,000/42,000: the bundle is 87,399 raw / 39,602 gzipped, up 3,263 raw / 1,062 gzipped, which fit the old 88,000/40,500 by only 601 bytes — thinner than this repository means a ceiling to be — andsrc/games.tssays so. The range and the example did not move a byte.One thing outside the issue:
cycleinspectate.tsnever marked a cut, so the camera eased between teammates instead of being placed, andmain.test.ts's spectate test failed about one run in four onmainas well as here. That is one line, plus a strengthened assertion inspectate.test.tsthat stands the next body 32 units away so only a real cut passes. I did not make the bots buy or throw grenades — they never have — so a flashed bot only happens when you throw one at them, and there is no generated-map pin work here beyond re-pinning #147's, since #159 has not landed.🤖 Generated with Claude Code
Budget reached at $8.60; this is where it stopped.
Closes #164