feat: overhaul movement for flow — momentum-preserving states, smooth crouch, landing feel

- Quake-style air-strafe accelerate (real speed gain from strafing; external
  speed from dash/rockets never clamped)
- Wall run: keeps entry momentum (incl. upward carry), accelerates along the
  wall instead of hard-setting velocity, gravity fades in over the run
- Slide: slope physics (gravity projected along floor accelerates downhill),
  flat-ground decel instead of multiplicative friction, entry boost, direct
  slide->wallrun and slide->dash transitions
- Dash: cooldown 10s -> 2s, per-player (was a static shared across instances),
  momentum fully kept on exit, FOV punch event
- Grapple: taut pendulum with active rope control (W reels in, S pays out),
  release keeps swing energy
- Wall climb: carries upward momentum in, jump-off kick, shared vault helper
- Crouch capsule: single owner in the machine, smoothly lerped, ceiling check;
  camera eye height follows via crouch factor (no more head snapping)
- Landing: machine emits 'land' events scaled by impact; camera dip + pitched
  down thud; footsteps get pitch variation
- Camera rig: event-driven (land dip, dash FOV kick, vault pitch impulse),
  slide roll tilt
- Model: Jump vs Fall split by vertical velocity, Land one-shot on heavy
  landings, wall-run body lean (synced to remotes via synced_wall_side)

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Nicholas Butzke
2026-07-17 11:58:14 -04:00
co-authored by Claude Fable 5
parent c4a538a469
commit 0ba14a9469
16 changed files with 653 additions and 493 deletions
+5 -2
View File
@@ -13,8 +13,8 @@ func enter(_data: Dictionary = {}) -> void:
elapsed = 0.0
stamina = params.wall_cling_max_stamina
machine.register_chain_mechanic("wall_cling")
# Kill most velocity but keep slight downward
machine.player.velocity = Vector3.ZERO
# Keep a touch of momentum so the stop reads as a grab, not a freeze
machine.player.velocity *= 0.15
func exit() -> void:
@@ -56,6 +56,9 @@ func update(delta: float) -> void:
machine.wall_cooldown_timer = 0.3
machine.register_chain_mechanic("wall_cling_jump")
machine.jump_cooldown_timer = params.jump_cooldown
machine.movement_event.emit("jump", {})
if machine.player.jump_player:
machine.player.jump_player.play()
machine.switch_to("air")
return