I am trying to implement simple Newtonian physics for my game. However, my character only jumps half of the height I would expect him to.

Physics says that the take-off velocity (impulse) v for an object to reach a height h is


Thus, to achieve a height of 2.0 meters, an impulse of 6.264 (per unit of mass) would be required. I used this as a benchmark to test the correctness of my physics code.

However, aforementioned impulse only raises my object 0.97 meters into the air before it falls down again.

I've tried Euler integration, Euler (midpoint) integration and Runge-Kutta 4 integration, all resulting in a jump height 0.97. My delta time is fixed to 1 / 120.

// Calculate the movement of the game object in this physics frame
Vector3 translation;
  Vector3 acceleration = this.queuedForces / this.Mass;

  // Convert impulses 
  Vector3 impulses = this.queuedImpulses / this.Mass;
  acceleration += impulses / delta; // turn impulse into force over 1 delta tick

  // Apply half of the force scaled by time
  this.Velocity += acceleration * delta / 2.0f;

  // Apply impulses directly to velocity
  //this.Velocity += this.queuedImpulses / this.Mass;

  // Integrate into position
  translation = this.Velocity * delta;

  // Apply second of the force scaled by time
  this.Velocity += acceleration * delta / 2.0f;

  // Finally, queued movements (root motion, etc.) go directly into translation
  translation += this.queuedMovement;

Gravity is a force, applied each tick as this.forces += Vector3(0, -9.81, 0) * this.Mass). The jump is an impulse added once as this.impulses += Vector3(0, 6.264, 0).

Where does my mistake lie?

Adding the impulse directly to this.Velocity instead of converting it to a force quadruples the jump height, which equally puzzles me.

  • \$\begingroup\$ Why split the velocity calculation? Even if you have a good reason to do so, why not simplify it while you identify your problem? \$\endgroup\$
    – House
    Sep 12, 2017 at 20:57
  • \$\begingroup\$ Because I believe this would be wrong and introduce a new problem to the simulation rather than make it clearer. The integration formula shown is the "Midpoint Method" (see openarena.ws/board/index.php?topic=5100.0 or lolengine.net/blog/2011/12/14/understanding-motion-in-games) and it matches up with Runge Kutta 4 very closely. \$\endgroup\$
    – Cygon
    Sep 12, 2017 at 21:12
  • \$\begingroup\$ Seems like a good troubleshooting starting point to me. Half the velocity being applied and half the height being achieved. \$\endgroup\$
    – House
    Sep 12, 2017 at 21:15
  • \$\begingroup\$ I am applying the other half of the acceleration a little further down. If I change it to apply the full acceleration before integrating velocity, my character jumps a tiny bit higher, if I do it after integrating velocity, a tiny bit lower. Both introduce an error of + and - (a * dt / 2) into the velocity. \$\endgroup\$
    – Cygon
    Sep 12, 2017 at 21:30

1 Answer 1


F=MA. Or, Force = Mass * Acceleration.

It appears you're dividing out the mass from your queued forces and impulses to deal with just acceleration, but you're not putting the mass back in when you calculate the force to be applied to the object. And I suspect the mass of your character is equal to 2?

this.Velocity += acceleration * delta / 2.0f;

should be

this.Velocity += (acceleration * mass) * delta / 2.0f;

You can also just not divide out the mass and just sum up forces instead of accelerations.

I wrote a quick test method to see this in action:

    static void Test()
        float delta = 1f/120f;
        float height = .001f;
        float impulse = 6.264f;
        float gravity = -9.81f;
        float mass = 2f;
        float velocity = 0;

        float peakHeight = 0;
        while (height > 0)
            float acceleration = gravity/mass;
            float impulses = impulse/mass;
            impulse = 0;
            acceleration += impulses/delta;
            velocity += (acceleration*mass)*delta/2f;

            height += velocity*delta;

            if (height > peakHeight)
                peakHeight = height;

            velocity += (acceleration*mass)*delta/2f;

        Console.WriteLine("PeakHeight: " + peakHeight);

Which outputs:

PeakHeight: 1.974736

  • \$\begingroup\$ That seems to be it! My test mass was 80.0, but I was using a gravity multiplier, too. In your code, If I use smaller deltas, the height converges on 2.0 (as expected) and if I change it to use 4th order Runge Kutta integration (also multiplying acceleration by mass) it agrees with the result -> ideone.com/xUzOTD \$\endgroup\$
    – Cygon
    Sep 13, 2017 at 7:00
  • \$\begingroup\$ Can you elaborate on what you mean by "You can also just not divide out the mass and just sum up forces instead of accelerations."? If I add gravity as a force via force += gravity * mass and not multiply by mass during integration, would that be correct? \$\endgroup\$
    – Cygon
    Sep 13, 2017 at 7:07
  • \$\begingroup\$ You'd leave mass out of that code entirely. Since it's been accounted for elsewhere when you calculated the forces. I'd assume you're already adding gravity as a force somewhere else, which is why you are dividing by mass to get back to an acceleration. \$\endgroup\$
    – House
    Sep 13, 2017 at 14:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .