Skip to content

feat(session): reject movement a client could not have made - #154

Open
xRookieFight wants to merge 1 commit into
devfrom
feat/movement-validation
Open

feat(session): reject movement a client could not have made#154
xRookieFight wants to merge 1 commit into
devfrom
feat/movement-validation

Conversation

@xRookieFight

Copy link
Copy Markdown
Contributor

Description

Movement was taken at face value: a client could report any position at all and the server would accept it, so flying and cross-world teleports cost nothing to fake. Attack reach was also a flat eight blocks regardless of game mode.

  • Every accepted movement report now has to be one the client could have reached from where the server last had it. Horizontal and vertical travel are budgeted separately - walking, flying and terminal velocity are different limits - and a report that exceeds its budget is not applied: the player is sent back to the position the server still believes in, through the same teleport-ack gate that already exists.
  • The budget is earned against the wall clock rather than the world's tick counter. Reports are coalesced and a world actor can fall behind, and neither should shrink the allowance a client legitimately earned in the meantime. It is capped, so standing still for an hour does not buy one jump across the map.
  • The Speed effect widens the horizontal budget by its own movement multiplier, so a speed-potion sprint is not read as cheating. Spectators and sessions that have not spawned are not checked.
  • Attack reach is now per game mode - four blocks in survival, six in creative - instead of eight for everyone, and the entity-interact path uses the same limit as the attack path.
  • The correction packet a cancelled on_player_move already sent is now shared with the rejection path, since the client has to be put back either way.

Some existing movement tests moved players several blocks in a single report to exercise scheduling and coalescing. Those distances were never the point of the tests, so they now use steps a player could actually take; every assertion they make is unchanged.

Related issue

Part of #146

Not in this PR: server-side collision resolution, so clipping through blocks is still not caught. That needs the block collision shapes to be complete enough to trust, and a wrong answer there teleports legitimate players into walls. Break-time verification, placement reach and the per-connection packet rate limit already existed and are untouched.

Checklist

  • v -check . is clean
  • v test green for movement_validation_test.v, movement_test.v, world_movement_test.v, world_switch_movement_test.v, combat_test.v, world_combat_test.v, effective_position_test.v, world_soak_test.v, world_concurrency_test.v
  • Follows the conventions in AGENTS.md (OOP, pub/capitalized exports, no import cycles, minimal comments)
  • Cross-session gameplay state is only mutated on its owning world's actor thread (via world_call/wr.submit/WorldTx), never through a global Hub actor
  • No unrelated changes bundled in

@xRookieFight
xRookieFight requested a review from a team as a code owner September 3, 2026 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant