s&box/field-guide
the symptom, in your words

"Double jump doesn't work with Jump() — set Velocity.z directly"

✓ verified on engine 26.07lane: Writing gameplayposted
▸ SYMPTOM

Your double-jump fires (the latch flips, the anim replays) but the character barely gains height — or gains none at all. The first jump works perfectly; the second one feels "swallowed."

▸ CAUSE

Jump() helper methods typically clamp the vertical impulse against the character's current upward velocity. During a double jump the character is already rising, so the clamp eats most or all of the second impulse. The method is designed for ground jumps where vertical velocity is zero or negative.

▸ FIX

Set Velocity.z directly instead of calling a jump helper:

snippet
void TryJump()
{
    bool grounded = MoverMode == MoveMode.Ground
                 || MoverMode == MoveMode.Slide
                 || InCoyoteTime;

    if ( grounded )
    {
        // First jump — normal
        Velocity = Velocity.WithZ( JumpSpeed );
        _hasDoubleJump = true;
        PlayJumpAnim();
    }
    else if ( _hasDoubleJump )
    {
        // Second jump — slightly higher + forward boost
        float secondImpulse = JumpSpeed * 1.25f;
        Velocity = Velocity.WithZ( secondImpulse );

        if ( InputDirection.Length > 0 )
            Velocity += InputDirection.Normal * ForwardBoost;

        _hasDoubleJump = false;
        PlayJumpAnim();
    }
}

Key details:

  • Gate on mover mode, not animation state. The animation's grounded flag is visual-only with hysteresis — it mis-arms the latch. Use the movement controller's actual mode (Ground, Slide, Air).
  • One air jump per airtime. Reset _hasDoubleJump when grounded or sliding.
  • Second impulse slightly higher (x 1.25) gives a satisfying feel — the player earned it by timing the press.
  • Re-trigger the jump animation on the second press for visual feedback.
▸ WHY IT WORKS

Velocity.WithZ( value ) replaces the vertical component outright instead of adding to it. There's no clamp, no "already rising" check — the character gets exactly the impulse you specified, regardless of current vertical state. This is the correct primitive for any mid-air impulse (double jump, wall jump, dash).

Verified on engine 26.07 — seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?