diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs
index c7ef05b12e..ad40e3a84a 100644
--- a/common/src/sys/phys.rs
+++ b/common/src/sys/phys.rs
@@ -219,7 +219,7 @@ impl<'a> System<'a> for Sys {
                 pos.0 += pos_delta / increments;
 
                 // While the player is colliding with the terrain...
-                while collision_with(pos.0, near_iter.clone()) && attempts < 32 {
+                while collision_with(pos.0, near_iter.clone()) && attempts < 12 {
                     // Calculate the player's AABB
                     let player_aabb = Aabb {
                         min: pos.0 + Vec3::new(-player_rad, -player_rad, 0.0),
@@ -283,7 +283,7 @@ impl<'a> System<'a> for Sys {
                         // ...and we're being pushed out horizontally...
                         && resolve_dir.z == 0.0
                         // ...and the vertical resolution direction is sufficiently great...
-                        && -dir.z > 0.5
+                        && -dir.z > 0.1
                         // ...and we're falling/standing OR there is a block *directly* beneath our current origin (note: not hitbox)...
                         && (vel.0.z <= 0.0 || terrain
                             .get((pos.0 - Vec3::unit_z()).map(|e| e.floor() as i32))
@@ -302,9 +302,10 @@ impl<'a> System<'a> for Sys {
                     } else {
                         // Resolve the collision normally
                         pos.0 += resolve_dir;
-                        vel.0 = vel
-                            .0
-                            .map2(resolve_dir, |e, d| if d == 0.0 { e } else { 0.0 });
+                        vel.0 = vel.0.map2(
+                            resolve_dir,
+                            |e, d| if d * e.signum() < 0.0 { 0.0 } else { e },
+                        );
                     }
 
                     attempts += 1;