Mojira MC-259487 · vanilla Minecraft source · LivingEntity.knockback / Entity.lerpMotion

The vanilla code behind the jump-reset

Why jumping on the tick you are hit cancels your knockback. The cancellation is a blend formula in the movement code; the strict "late is fine, early fails" timing is an artifact of how the result travels back to you over the network as an overwrite.

#01The one idea

Two layers, two questions. The movement code explains why a sprint-jump cancels knockback. The netcode explains when you have to do it.

When you are hit, LivingEntity.knockback sets your new horizontal velocity to oldVelocity / 2 − knockback. It blends, it does not replace. So velocity you already carry toward the attacker is halved and then subtracted from the knockback that pushes you away. A sprint-jump injects a burst of velocity in your look direction — straight at the enemy — so when the blend folds it in, most of the horizontal knockback cancels and you keep your ground. That is the mechanism, and it is entirely in vanilla movement code.

But in multiplayer the hit is resolved on the server, and the result is shipped back to you as a velocity packet that overwrites your local motion. That single fact — overwrite, not blend, applied after a network delay — is why you can jump on time or late but never early: anything you do before the packet lands is discarded by the overwrite, and anything after it survives. The timing window you feel is the shape of that round trip.

Source basis

All code is decompiled Minecraft from the multi-version tree on disk: modern snippets are Mojang-mapped (the knockback$v1_17_0 variant spans 1.17 through 26.x, covering the affected 1.19.3 / 1.20.6); 1.8.9 snippets are MCP-named. Decompiler artifacts are lightly cleaned, logic untouched. Where a claim rests on architecture rather than a line I could open, it is flagged.

#02What the report says

The bug as Mojang records it.

FieldValue
Key / SummaryMC-259487 — Jumping just as you're attacked allows you to take little to no horizontal knockback
StatusOpen ● unresolved · Confirmation: Community Consensus
Affects1.19.323w04a1.20.624w44a
Duplicated byMC-278103 Jumping can reset player's velocity · MC-272128 Vertical/reduced knockback when hit while jumping

Verbatim: "While sprinting forward, when you press your jump key at the same time when you get attacked, you will take reduced/no horizontal knockback depending on how accurately you time it." Both halves are load-bearing in the code below: it requires sprinting forward (the forward velocity does the cancelling) and it is timing- and ping-dependent (the jump must align with how the hit is registered and sent back).

#03Root cause: knockback blends, it never overwrites

The single line the whole exploit rests on, in LivingEntity.knockback.

// net/minecraft/world/entity/LivingEntity.java  —  knockback$v1_17_0 (1.17 → 26.x)
public void knockback(double strength, double x, double z) {
   strength *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
   if (!(strength <= 0.0)) {
      this.needsSync = true;                             // mark velocity dirty → server will sync it
      Vec3 dm = this.getDeltaMovement();                 // your CURRENT velocity
      Vec3 kb = new Vec3(x, 0.0, z).normalize().scale(strength);
      this.setDeltaMovement(
          dm.x / 2.0 - kb.x,                              // horizontal: HALVE old, then subtract knockback
          this.onGround() ? Math.min(0.4, dm.y / 2.0 + strength) : dm.y,
          dm.z / 2.0 - kb.z);                             // same on Z
   }
}

The horizontal result is not −kb; it is dm/2 − kb. Your pre-hit velocity is a first-class input to the knockback you receive. If dm.x points toward the attacker (the negative of the knockback direction), it cancels into kb.x and the magnitude collapses. The faster you are already moving into the hit, the less knockback you take. Note the needsSync = true: this same call flags your velocity dirty, which is what later sends it across the wire in §6.

#04The lever: a sprint-jump injects velocity toward the attacker

Jumping is not only vertical. While sprinting it adds a horizontal burst in your look direction — and in a duel you are looking straight at the enemy.

// LivingEntity.java  —  jumpFromGround()
public void jumpFromGround() {
   float jumpPower = this.getJumpPower();                 // 0.42 at baseline
   if (!(jumpPower <= 1.0E-5F)) {
      Vec3 v = this.getDeltaMovement();
      this.setDeltaMovement(v.x, Math.max(jumpPower, v.y), v.z);
      if (this.isSprinting()) {
         float yaw = this.getYRot() * 0.017453292F;       // degrees → radians
         this.addDeltaMovement(new Vec3(-Mth.sin(yaw) * 0.2, 0.0, Mth.cos(yaw) * 0.2));
      }                                                    // +0.2 in the facing direction
   }
}

The sprint clause adds 0.2 of horizontal speed pointed where you face. Stack it on normal sprint momentum (~0.28/tick) and, on the jump tick, dm toward the attacker peaks near 0.48. Feed that into dm/2 − kb and the subtraction nearly zeroes out. The jump also sets v.y to the jump power, so the vertical survives — hence "you popped up but barely moved back."

Why "while sprinting forward" is mandatory

Stand still and jump, and dm.x ≈ 0, so dm.x/2 − kb.x ≈ −kb.x — full knockback. The cancellation comes entirely from your forward velocity; the jump's job is to spike that velocity at the decisive moment. No forward sprint, no reset.

#05The local tick: a tight window with no network

In singleplayer there is no packet. The hit and your jump are resolved in the same tick, and the in-tick order is the whole story — which is why the window here is only a tick or two.

Within one tick — LivingEntity.aiStep() order
  1. Jump phase. If this.jumping && onGround && noJumpDelay == 0, call jumpFromGround() — injecting the forward burst into deltaMovement.
    aiStep() · profiler.push("jump") · line ~2600
    injects velocity
  2. Knockback blend. The attacker's hit runs knockback()dm/2 − kb — folding your freshly-spiked forward velocity into the result.
    LivingEntity.knockback() · the dm/2 − kb line
    root cause
  3. Travel & friction. travel() applies movement and friction (airborne ≈ 0.91/tick, ground ≈ 0.55). With horizontal already small, what remains decays.
    aiStep() · profiler.push("travel") · line ~2634
    decays result

For the blend to cancel, your forward velocity has to be present in dm at the instant knockback() runs. With everything local and same-tick, that alignment is narrow — the one-or-two-tick window players describe offline. Multiplayer is where it widens, and where the asymmetry appears.

#06Across the wire: the hit comes back as an overwrite

In PvP the hit is resolved on the server and pushed to you as a velocity packet. How that packet is applied is the hinge of the entire timing model.

Your movement is client-authoritative: every tick your client simulates your player (§5) and reports the resulting position to the server, which trusts it within anti-cheat limits. Knockback is the exception — it originates server-side. The server runs knockback() on its copy of you, the needsSync flag from §3 marks your motion dirty, and the entity tracker sends you a ClientboundSetEntityMotionPacket. When it arrives, your client applies it:

// net/minecraft/world/entity/Entity.java  —  lerpMotion(), invoked by the SetEntityMotion packet
public void lerpMotion(double x, double y, double z) {
   this.setDeltaMovement(x, y, z);   // a hard SET — your current velocity is DISCARDED, not blended
}

That is the crux. The server's blend already happened with the server's view of your velocity; what reaches your client is an absolute value that replaces your local motion wholesale. So there are two distinct moments — the server resolving the hit, and your client overwriting — separated by your latency:

Multiplayer round trip — one hit
  1. Server resolves the hit. knockback() blends dm/2 − kb on the server's copy of you and flags your motion dirty.
    server tick T · LivingEntity.knockback() + needsSync
    server-side blend
  2. Velocity packet in flight. The dirty flag makes the server send SetEntityMotion back to you. It does not arrive instantly.
    in flight ≈ RTT/2 (your ping)
    latency
  3. Your client overwrites. lerpMotion → setDeltaMovement replaces your local velocity with the server's knockback. Everything you did before this instant is gone.
    LocalPlayer · the decisive moment
    overwrite

#07Why you can be late but never early

The overwrite plus client authority produce a one-sided window: velocity created before the packet is erased, velocity created after it survives.

Jump early → full knockback

If your jump fires before the packet lands, your forward burst moves you and is reported — then SetEntityMotion arrives and setDeltaMovement overwrites it with the server's full knockback. Your work is discarded and you eat the whole hit. This is why an early jump does not just fail to help, it fails: there is nothing your pre-hit velocity can do that the overwrite will not erase.

Jump on time or late → reduced knockback

Once the overwrite has landed, your local velocity is the knockback, and authority is yours again. A jump now re-injects the +0.2 forward boost, and holding W keeps travel() adding forward acceleration each tick, cutting the residual backward velocity before it carries you far. A jump on the exact overwrite tick is the "0-tick" perfect reset; later jumps still help while the backward velocity is large.

The window has a width for two compounding reasons. First, latency shifts the clock: the packet may not reach you until several ticks after the server's hit tick, so "late on the server's clock" is "on time on yours" — more ping, wider window. Second, the knockback decays slowly: airborne friction is ~0.91/tick, so the backward velocity persists for several ticks during which re-adding forward still meaningfully cuts displacement. Past roughly that span the knockback has already moved you and re-jumping stops mattering. A reported ~6-tick ceiling reads as the ping window plus those few still-cancellable ticks.

The cross-check

Players cite two windows: ~1–2 ticks and ~6 ticks. That is the same mechanism in its two regimes. Singleplayer has no packet and no overwrite, so it is the pure same-tick blend of §5 (tight). Multiplayer layers the overwrite-plus-latency window on top (wider, and one-sided). The window literally grows with latency — which is the tell that the timing is a netcode artifact, not part of the knockback math.

Honest limit of this account

Verified directly in source: the server-side blend (dm/2 − kb + needsSync) and the client-side overwrite (lerpMotion → setDeltaMovement). Reasoned from architecture, not a line opened here: the packet's exact send timing, and whether the server's dm term reflects your live forward velocity at hit-time (the part that makes a "0-tick" jump cancel server-side too). Strictly, "never early" is a multiplayer/overwrite rule; in a pure local blend, a hair-early jump could still help.

#08The arithmetic

Plugging illustrative numbers into dm.x/2 − kb.x with a base knockback of 0.4. Positive = toward attacker, negative = pushed back.

Forward velocity dm.x at the blendHorizontal resultEffect
Standing still · 00/2 − 0.4 = −0.40Full knockback ● flung back
Sprinting in · ≈ 0.280.28/2 − 0.4 = −0.26Reduced ("w-tapping") ● partial
Sprint-jump aligned · ≈ 0.480.48/2 − 0.4 = −0.16Mostly cancelled ● holds ground

Magnitudes are illustrative (base strength 0.4; sprint speed and the +0.2 boost approximate). The trend is the point: the larger your forward velocity when the blend runs, the smaller the surviving knockback.

#091.8.9 vs 1.17+: same root, one modern detail

The blend is ancient, which is why jump-resetting predates the report by a decade.

// 1.8.9  net/minecraft/entity/EntityLivingBase.java  —  knockBack()
this.motionX /= 2.0; this.motionY /= 2.0; this.motionZ /= 2.0;   // same halving
this.motionX -= var3 / var7 * 0.4;                               // same subtract
this.motionY += 0.4;                                            // vertical pop is UNCONDITIONAL
this.motionZ -= var5 / var7 * 0.4;
if (this.motionY > 0.4) this.motionY = 0.4;

1.8.9 halves-and-subtracts exactly like modern, so the horizontal reset works identically. The only difference is vertical: 1.8.9 always adds the 0.4 pop, whereas modern gates it on onGround (this.onGround() ? Math.min(0.4, dm.y/2 + strength) : dm.y). So since 1.17 a hit taken while airborne also skips the upward launch. That is a secondary sweetener; the shared, load-bearing cause across every affected version is the horizontal blend.

#10Where a fix would live, and why it is still open

The behavior is two vanilla methods plus the netcode that connects them.

Resolving MC-259487 means changing LivingEntity.knockback (stop blending the victim's own velocity into horizontal knockback, or clamp it), jumpFromGround (don't inject horizontal velocity that can oppose a simultaneous hit), or how knockback is reconciled between server and client (the overwrite is what hands players the late window). All three are core systems Mojang owns. The ticket sits at Open / Community Consensus because the behavior is load-bearing competitive tech: any of those changes alters how every PvP hit feels, so it is a balance decision as much as a code one.

#Where to look

Vanilla method / fieldClassRole in the bug
knockback(...) (knockback$v1_17_0)LivingEntityThe dm/2 − kb blend — root cause; sets needsSync
jumpFromGround()LivingEntityInjects 0.42 up + 0.2 forward sprint burst
aiStep()LivingEntityRuns jump before travel — sets the same-tick window
lerpMotion()setDeltaMovement()EntityVelocity packet OVERWRITES local motion — source of the early/late asymmetry
needsSync / markHurt()EntityDirty flag that triggers the server→client velocity packet
travelInAir(...)LivingEntityAir (0.91) vs ground (~0.55) friction — how the result decays
knockBack(...) / jump()EntityLivingBase (1.8.9)Same blend; vertical pop unconditional

Sources: Mojira MC-259487 (description + comments, bugs.mojang.com API) · decompiled Minecraft — LivingEntity.java & Entity.java (modern, mojmap), EntityLivingBase.java (1.8.9, MCP) · Minecraft Wiki, Knockback (mechanic). Server packet timing reasoned from architecture; velocity magnitudes illustrative.