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

A bullet that lands does not slow the player it hits: no tagging, so trading a shot costs the enemy nothing #189

shipped merged opened this has it
opened this

Make a hit slow the player who took it, the way CS's tagging does, so a shot that lands buys the shooter the exchange.

shoot in src/client/world.ts:787 resolves damage, pushes hurt (a vignette, a wedge and a pain sound for the person, world.ts:725) and calls flinch for view punch — and touches the victim's velocity nowhere. A player sprinting into the open who takes 30 in the chest keeps all 250 u/s of it, so hitting someone first is worth nothing but the damage: there is no way to stop a push with one bullet, no reason to hold an angle, and no trade. It is the last CS movement rule the repository does not have (friction, air acceleration, the 18-unit step, strafe jumping, crouch and walk speeds are all in physics.ts).

The shape to keep: flinch is deliberately outside the tick because punch is two of the policy's 32 inputs (observe.ts) and moving it would move the numbers the shipped weights were trained on. Tagging cannot take that escape — a slow that only applies to world.me would be a handicap on the person alone — so it goes in the tick, symmetrically, and the cost is measured rather than assumed.

Done looks like:

  • [ ] A hit scales the victim's ground speed for a short, decaying window: one named constant per part (how much a point of damage takes, the floor it cannot go under, how fast it recovers), stated in units and seconds, applied in applyInput/move's wish speed and not by editing vel directly.
  • [ ] Symmetric: a bot shooting the person and the person shooting a bot produce the same slow, through the same code path, for every player in world.players.
  • [ ] Airborne is unaffected (CS does not tag a player in the air) and the slow never survives a round start — startRound clears it with punch at world.ts:479.
  • [ ] Tests that fail without it: a player at full speed hit for 30 moves measurably less far over the next half second than the same player not hit; the slow decays to nothing by the stated time; two hits do not stack past the floor; a player in the air is not slowed; startRound clears it.
  • [ ] Measured, not assumed: bun run scripts/measure.ts (or scripts/duel.ts) run before and after on the same seeds, with both numbers in the pull. A policy win rate that moves more than a couple of points is a finding to report, not a reason to hide the rule.
  • [ ] README's What is real and what is not gains the rule in one sentence with its numbers, beside the flinch and hit-feedback text it already has.

Files I expect to change: src/client/world.ts, src/client/world.test.ts, possibly src/client/physics.ts (if the speed cap is expressed there), README.md.

Risks: this is a simulation change the trained policy observes through its own velocity, so the arena is the gate — measure it. It also makes the person's own movement worse in a fight they are losing, which is the point; keep the constants small (a hit is a hesitation, not a stun) and say what you chose. Do not touch flinch, the damage numbers or the hitgroup table.

Waits on #185, which is already rewriting the same movement-speed plumbing in world.ts (weapon switch and carrySpeed); two pulls in that code at once is a conflict for nothing.

Suggested: vesper.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs