diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Jumper.java b/src/main/java/com/minelittlepony/unicopia/entity/Jumper.java
new file mode 100644
index 00000000..ece487da
--- /dev/null
+++ b/src/main/java/com/minelittlepony/unicopia/entity/Jumper.java
@@ -0,0 +1,5 @@
+package com.minelittlepony.unicopia.entity;
+
+public interface Jumper {
+    boolean isJumping();
+}
diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java
index 0a2eebc2..21fabe58 100644
--- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java
+++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java
@@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.Race;
 import com.minelittlepony.unicopia.USounds;
 import com.minelittlepony.unicopia.ability.magic.Spell;
 import com.minelittlepony.unicopia.entity.EntityPhysics;
+import com.minelittlepony.unicopia.entity.Jumper;
 import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
 import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
 import com.minelittlepony.unicopia.projectile.ProjectileUtil;
@@ -50,16 +51,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
         dimensions = new PlayerDimensions(pony, this);
     }
 
-    @Override
-    public float getGravityModifier() {
-        if (pony.getMaster().getAttributes() == null) {
-            // may be null due to order of execution in the contructor.
-            // Will have the default (1) here in any case, so it's safe to ignore the attribute a this point.
-            return super.getGravityModifier();
-        }
-        return super.getGravityModifier() * (float)pony.getMaster().getAttributeValue(PlayerAttributes.ENTITY_GRAVTY_MODIFIER);
-    }
-
     @Override
     public PlayerDimensions getDimensions() {
         return dimensions;
@@ -77,6 +68,8 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
         }
         PlayerEntity entity = pony.getMaster();
 
+        final MutableVector velocity = new MutableVector(entity.getVelocity());
+
         if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) {
             float currentHeight = entity.getDimensions(entity.getPose()).height;
             float sneakingHeight = entity.getDimensions(EntityPose.STANDING).height;
@@ -85,8 +78,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
             entity.setPose(EntityPose.STANDING);
         }
 
-        final MutableVector velocity = new MutableVector(entity.getVelocity());
-
         boolean creative = entity.abilities.creativeMode || pony.getMaster().isSpectator();
 
         FlightType type = getFlightType();
@@ -118,7 +109,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
         isFlyingSurvival = entity.abilities.flying && !creative;
         isFlyingEither = isFlyingSurvival || (creative && entity.abilities.flying);
 
-        if (pony.getPhysics().isGravityNegative()) {
+        if (isGravityNegative()) {
             entity.setOnGround(!entity.world.isAir(new BlockPos(entity.getX(), entity.getY() + entity.getHeight() + 0.5F, entity.getZ())));
 
             if (entity.isOnGround() || entity.horizontalCollision) {
@@ -126,6 +117,10 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
                 isFlyingEither = false;
                 isFlyingSurvival = false;
             }
+
+            if (entity.isClimbing() && (entity.horizontalCollision || ((Jumper)entity).isJumping())) {
+                velocity.y = -0.2F;
+            }
         }
 
         if (type.canFly()) {
diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java
index c386c4a4..921d1b69 100644
--- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java
+++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java
@@ -4,6 +4,7 @@ import java.util.Optional;
 
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.gen.Accessor;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Constant;
 import org.spongepowered.asm.mixin.injection.Inject;
@@ -18,6 +19,7 @@ import com.minelittlepony.unicopia.entity.PonyContainer;
 import com.minelittlepony.unicopia.entity.behaviour.Disguise;
 import com.minelittlepony.unicopia.entity.player.Pony;
 import com.minelittlepony.unicopia.entity.Equine;
+import com.minelittlepony.unicopia.entity.Jumper;
 import com.minelittlepony.unicopia.entity.ItemWielder;
 
 import net.minecraft.entity.Entity;
@@ -30,7 +32,7 @@ import net.minecraft.util.Hand;
 import net.minecraft.util.math.BlockPos;
 
 @Mixin(LivingEntity.class)
-abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<?>>, ItemWielder {
+abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<?>>, ItemWielder, Jumper {
     @Shadow
     protected ItemStack activeItemStack;
     @Shadow
@@ -59,6 +61,10 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
         return caster;
     }
 
+    @Override
+    @Accessor("jumping")
+    public abstract boolean isJumping();
+
     @Inject(method = "createLivingAttributes()Lnet/minecraft/entity/attribute/DefaultAttributeContainer$Builder;", at = @At("RETURN"))
     private static void onCreateAttributes(CallbackInfoReturnable<DefaultAttributeContainer.Builder> info) {
         Creature.registerAttributes(info.getReturnValue());