Sitelet https://github.com/VortexFPS/VortexArena/pull/15
Skip to content

Soft player collision: pass-through movement + push-apart separation - #15

Open
bryankruman wants to merge 2 commits into
mainfrom
feature/player-soft-collision
Open

bryankruman wants to merge 2 commits into
mainfrom
feature/player-soft-collision

Conversation

@bryankruman

Copy link
Copy Markdown
Collaborator

What

Replaces hard player-vs-player body-blocking with soft collision (on by default, sv_player_softcollision 0 restores stock behavior):

  • Pass-through: new MoveFilter.NoPlayers — clips exactly like Normal except player bodies (SOLID_SLIDEBOX + FL_CLIENT) never block. All player movement-hull traces in PlayerPhysics (main slide/PushEntity, ground downtrace, ramp check, crouch stand-up, IsFlying) route through a cvar-gated PlayerClipFilter(). Running through someone at speed is a clean slip; you can deliberately walk through a standing player.
  • Push-apart: new server-side PlayerSeparation pass (first step of GameWorld.OnEndFrame, after all players have moved). Overlapping hulls slide apart positionally — horizontal-only, split symmetrically, at sv_player_softcollision_pushspeed (default 150 u/s per pair) with each step capped at the remaining penetration, so bodies ease out and settle exactly side by side (no jitter at contact, no fling).

Why

Requested gameplay change for Vortex Arena: fast crossing paths should have minimal interaction; standing overlap should gently resolve to adjacent positions; body-blocking should be impossible.

Reviewer notes

  • Weapons unaffected: only movement traces use the new filter — hitscan/melee/projectile traces keep their existing filters, so players stay fully shootable. Monsters (SLIDEBOX + FL_MONSTER) still block movement.
  • Prediction stays in lockstep: sv_player_softcollision rides the MoveVarsBlock wire (v9, slot 50, append-only; AbsentDefaults carries the unset→ON semantics), read ambiently by PlayerPhysics like sv_gameplayfix_nudgeoutofsolid. The separation push itself is server-only/unpredicted — at ≤75 u/s per body the reconcile smoothing absorbs it.
  • Separation is positional, not an impulse: ground friction (~800 u/s² at rest) would eat any reasonable velocity-based push; a trace-guarded origin slide sidesteps that and stops naturally at contact.
  • Guard rails: pushes are trace-guarded against world geometry (NoPlayers filter so a third body can't wedge the push), never vertical, skip dead bodies/spectators, keep frozen statues immobile (free body absorbs the full push), and use a deterministic pair-keyed direction for fully co-located bodies (no RNG stream advances). Moved bodies are relinked into the entity area grid.
  • Incidental fix: docs/reference/CVARS.md had committed merge-conflict markers inside the generated inventory — cleaned up during the regen (which also picks up the two new cvars).
  • Tests: new PlayerSoftCollisionTests (filter skip vs players/monsters, settle-adjacent, symmetric midpoint, one-tick deflection bound, cvar off, dead-body exemption); SnapshotDeltaTests wire-count pin updated 49→50. Full suite: 2991 green.
  • Not yet playtested in-game — worth a bot match to tune sv_player_softcollision_pushspeed by feel.

🤖 Generated with Claude Code

bryankruman and others added 2 commits July 11, 2026 18:21
…ftcollision)

Players no longer hard-block each other's movement. The movement hull traces
switch to a new MoveFilter.NoPlayers (clips like Normal, but SOLID_SLIDEBOX +
FL_CLIENT bodies never block), so crossing paths at speed is a clean slip and
you can walk through someone deliberately. Overlapping bodies are resolved by
a new server-side PlayerSeparation pass (GameWorld.OnEndFrame): a gentle,
symmetric, horizontal-only positional slide (sv_player_softcollision_pushspeed,
default 150 u/s per pair) that eases out exactly at contact, so co-located
players settle side by side without jitter or fling. Trace-guarded against
world geometry; frozen statues stay put; weapon/hitscan/melee traces are
untouched (players stay fully shootable); monsters still block.

sv_player_softcollision defaults ON (0 restores stock solid players) and rides
the MoveVarsBlock wire (v9, slot 50) so remote-client prediction picks the same
clip filter as the authority.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	docs/reference/CVARS.md

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant