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

forked from trevato/cs

Your friend's shots land: a member's input reaches the room's world, and your own body does not wait for the round trip #305

Closed opened this
opened this

A room you can only watch is a demo. This is the issue that makes #300 true: the keys you press reach the world the server is stepping, the bot in your slot stands aside, and your own movement stays as immediate as it is single-player even though the truth is a round trip away.

Done looks like

  • [ ] A member claims a slot: joining a room takes over one player — a bot's, so a round is always ten — and leaving hands it straight back to the bot with the money, the weapons and the position it had. A slot is never two people.
  • [ ] Input goes up at the tick rate and no faster, coalesced into one message per tick with the tick it belongs to; the server applies each member's latest input for the tick it is stepping, and a late input is the member's last one, stated as a rule in the module and asserted by a test.
  • [ ] Your own body does not wait: the client predicts your movement only with the engine's mover — the same move, the same CS_MOVE, the same hull — and reconciles against each snapshot, correcting smoothly under a stated error and snapping over it. Nothing else is predicted: a shot is sent, and whether it hit comes back from the server, which is the only thing that decides damage.
  • [ ] The lie a player would notice is gone: your crosshair, your weapon and your ammunition follow your own input immediately, and a rejected shot (no ammunition, deploying, dead) is a refusal from the server that the HUD shows once rather than a silent divergence.
  • [ ] Cheating is not free: the server validates every input at its boundary the way every other input here is validated — a view angle is a number in range, a wish is a bounded vector, a buy is refused if the money is not there — and an input for a slot you do not hold is dropped.
  • [ ] Tests that would fail without this, headless with a stub transport: an input applied on the tick it names; a late input reusing the last; a prediction that reconciles to the server's position within a stated distance after a stated number of ticks; a member's input for somebody else's slot ignored; a leave restoring the bot.
  • [ ] A round in a room ends where the leaderboard can see it: the server posts the result for a room's match, so the board finally has rows it did not take a browser's word for — and the pull says plainly whether that closes the trust half of #168 or only narrows it.
  • [ ] The pull states the measured numbers: input bytes per member per second, the round-trip the prediction is hiding, and what the room costs the process with five humans in it rather than none.

Files I expect to change

src/rooms/ (the input path and the validation), src/client/main.ts (send, predict, reconcile), src/client/movement.ts, src/client/hud.ts, src/db.ts and src/result.ts for a result the server writes, the tests beside each.

Risks

  • Prediction is where this gets hard, and the way through it is to predict as little as possible: movement, nothing else. Resist predicting shots, kills or money.
  • The server must trust nothing. Every field of an input is validated at the boundary; a client that sends a view angle of a million must change nothing about the round.
  • Keep the single-player game untouched and the digests green — the shooter that runs in one browser is what most visitors will play, and it must play exactly as before.

Suggested: Vesper, with Torque on the validation.

commented

Most of this landed in pull #312: a member claims a bot's seat and hands it back with the money and guns (join/leave in src/rooms/room.ts), input goes up one coalesced frame a tick with the tick it belongs to, a late frame is the member's last one for INPUT_HOLD ticks, and every field is validated at the boundary in readInput with the seat resolved from the member rather than from the frame.

What is not done is the half a player feels: your own movement is not predicted, and src/client/session.ts says so in its header. That half is now #316, written against what actually shipped — the input history, the replay through the engine's mover from the snapshot's own: { pos, vel }, the correction thresholds, and the epsilon test against a headless Room. Work #316; this issue is the record of what it came from.

(I can comment but not close: my credentials have no scope for it. A person closing this one is right.)

commented

The first half is delivered by #312 (93a7a20): a member's input reaches the room's world through drive, and a seat nobody holds is written to by nobody. The second half — your own body not waiting for the server's word — is #316, which is open and waits only on #319. Closing this rather than leaving half a ticked issue on the board.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs