Conserving Energy in Physics Simulations 08-21-02 This is kind of a bone-headed trick, but it helps a lot and it's very simple. Lots of gameplay is physics, whether the coder thinks of it that way or not. At some point you will start running into issues like sampling problems, and the fact that your integrator isn't very good, and that all causes weird glitchy behavior. Let's consider a simple case - a ballistic object moving in gravity. We'll work in one dimension - just "z" (vertical). Your physics equations are : z' = v v' = - g where ' means rate of change with respect to time (read "prime"). You can solve this exactly; the solution is : z(t) = z(0) + t * v(0) - 0.5 * g * t^2 But in games you normally wouldn't do that, because there may be other forces acting on your object which mean you can't just use an exact solution. So what if I just used a simple Euler integrator? The Euler integrator advances timesteps like this : z(t+dt) = z(t) + v(t) * dt v(t+dt) = v(t) - g * dt That's ok if you do lots of steps with small dt, but if your time step dt is ever large, the solution for z(t+dt) is very far off what it should be. Part of the problem is that we're violating conservation of energy in each time step. We can easily fix this, though. The energy of the system at any time is : E = 0.5 * m * v^2 + m * g * z This is just the sum of the kinetic energy and the gravitational potential energy. So, we can easily figure out our initial energy : E(0) = 0.5 * m * v(0)^2 + m * g * z(0) This is equal to the energy at all times, so we can write E(t) = E(0) and solve for v(t) : v(t) = sqrt{ v(0)^2 + 2 * g* ( z(0) - z(t) ) } So, we can do a new integrator by incorporating this : z(t+dt) = z(t) + v(t) * dt v(t+dt) = sqrt{ v(t)^2 + 2 * g * v(t) * dt } This is a simple Euler integration of z(t) , and then an exact fix-up for v(t). If you're a physics wiz, what we're doing here is keeping our particle on the correct curve in phase space. Phase space is the {z,v} plane, and all particles should move on curves in phase space which conserve energy. So, with this integrator, we may not move the right *amount* on a curve, but we always stay on the right curve. If you preferred, you could Euler integrate "v" and exactly fix "z", but in practice it's very useful for "z" to change only once, and to change linearly, so that you can do collision detection with a linear sweep.