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

forked from trevato/cs

Switching a weapon costs the time it costs in Counter-Strike: a deploy time, so the knife is a decision #269

Merged opened this

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

Merged

Pushed. `bun test` is green (1180 pass, 0 fail) and the typecheck is clean.

shipped production is serving it deploy ae07c2d

opened this

Pushed. bun test is green (1180 pass, 0 fail) and the typecheck is clean.

Every weapon in src/client/weapons.ts now carries a deployTime in seconds — CS's draw times, 0.7 s for the pistols and the MP9, 1.0 s for the rifles and the knife, 1.25 s for the AWP, and GRENADE_DEPLOY 0.5 s for the three thrown things, which nothing deploys because a grenade is thrown out of a pocket rather than held. The paragraph above WEAPON_LIST says where each number came from. applyInput charges it on a switch and on nothing else: deployTicks rounds the seconds up to whole ticks of the simulation's own clock (the AWP's 1.25 s is 80 ticks, a rifle's or the knife's 1.0 s is 64, a pistol's 0.7 s is 45 — 44.8 rounded up), and until deployUntil passes the player cannot fire, scope or start a reload. The carry speed still changes on the tick of the switch itself; that asymmetry is commented where it happens. Spawning is not switching — startRound, the half-time side swap and the arena's equip all clear the timer — and bots reach it through the same input.switchTo into the same applyInput, so no bot bypasses it. The HUD says "switching" in the line that says "reloading".

The tests state their arithmetic: 63 ticks of holding the trigger after a knife draw send nothing and the 64th sends the swing; the USP answers on tick 45 and not 44; the body is already past the AWP's 200 u/s one tick into the knife draw and settles at the knife's 250, and coming back to the AWP costs 80 ticks of no trigger and no scope, where before this it cost nothing; the knife run pays for itself past 1,250 units (d/1000 s saved against 1.25 s of deploy); a switch mid-reload still cancels it and the restart waits for the new weapon to be up.

On the golden digests, which is the one place this pull does not do what the issue expected. ROUND, DUEL and the two generated matches do not move, and that is checked rather than assumed: the only two switches in the pinned forty seconds are Tundra drawing a knife at tick 1522 and Pike at tick 1582, and neither is inside knife range for the 64 ticks it now costs them, so no swing was refused, no accuracy roll was skipped and no hashed field changed. Rather than widen the hash to force movement, I followed the pattern #165 set for smoke and added a run that is the rule: SWITCH_SCRIPT in replay.ts and SWITCH_ROUND in replay.test.ts — twenty seconds of seed 7 on de_forge where the person taps 3 to run, swings inside the deploy and misses, taps 2 with the trigger held and gets the first round out on tick 813, then cancels a reload with a switch and restarts it late. Its freeze hashes identically to ROUND's for seven seconds and parts at second 8. A second test walks that run tick by tick and asserts no shot ever left inside a deploy window. deployUntil is deliberately not in PLAYER_FIELDS, on the same footing as reloadUntil.

To try it in the preview: buy an AWP, tap 3 and run a long sightline, then tap 1 at the other end — the readout reads "switching" and the trigger is dead for a quarter of a second longer than a rifle's.

🤖 Generated with Claude Code

Closes #143

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs