TT Lab
Get started
Learn Learning paths Courses

The Skeleton of a Physics Engine

Why Euler Adds Energy

Continue in TT Lab

In one line

There are several ways to get velocity from acceleration and position from velocity, and explicit Euler adds a little energy at every step in an oscillating system. Semi-implicit Euler, which only swaps the order, does not.

Why this was needed

What a physics engine solves is differential equations. Force gives acceleration, integrating acceleration over time gives velocity, and integrating velocity gives position. A computer cannot do continuous integration, so it approximates by cutting time into small pieces.

The problem is that the approximation does not merely introduce error; it changes the properties of the system itself. A weight hanging on a spring should oscillate with the same amplitude forever, but if you compute with the simplest method, the amplitude keeps growing and flies off the screen in a few seconds. It is not that the force calculation is wrong; the integration method is wrong.

How it works

Explicit Euler uses only the values at the start of a step.

x_new = x + v * dt
v_new = v + a(x) * dt

If you feed it a spring (a = -x, with mass and stiffness both 1), one step becomes a linear transformation, and you can compute the amplification factor of that transformation exactly. The energy E = (x² + v²)/2 is multiplied by exactly (1 + dt²) at every step. With dt=0.05 and 400 steps, 1.0025^400 ≈ 2.715 times. It is not error but a systematic increase. Reducing dt only makes it slower; the direction stays the same.

Semi-implicit (symplectic) Euler only swaps the order.

v_new = v + a(x) * dt
x_new = x + v_new * dt        # 방금 구한 새 속도를 쓴다

You only swapped the order of the lines, yet the properties become completely different. This method exactly preserves another quantity very close to the original energy, so the energy only oscillates within a small range and does not diverge. This is why almost all game physics engines use it. The computational cost is the same as explicit Euler.

Velocity Verlet uses acceleration twice within one step.

x_new = x + v * dt + 0.5 * a * dt²
a_new = a(x_new)
v_new = v + 0.5 * (a + a_new) * dt

The accuracy is one order higher (second order in dt), so the error is much smaller at the same dt, and it also keeps the symplectic property. It is the standard in places that must run for a long time accurately, such as molecular dynamics. In exchange, one more force calculation is needed per step.

What matters here is that accuracy and stability are different axes. The problem with explicit Euler is not that it is inaccurate, but that the direction in which it gets worse over time is fixed.

It is worth looking a little further into why one change of order makes such a big difference. If you write one step of explicit Euler as a matrix, the determinant of that matrix is 1 + dt², greater than 1. A determinant means how many times the area grows in phase space, so at every step the state space swells a little. The determinant of semi-implicit Euler is exactly 1. It is an area-preserving transformation, so it cannot diverge. This property is what the word symplectic means.

Let me point out one misunderstanding. What a symplectic integrator preserves is not the energy itself. It exactly preserves another quantity very close to the original energy, and as a result the energy only rises and falls within a small range and does not drift in one direction. That is why, in the lab, the energy curve of semi-implicit Euler comes out not as a flat straight line but as a thin oscillating band. That is normal.

What it looks like in the field

A variable time step causes accidents. If a frame is late once and dt gets large, in that step an object passes through a wall or a constraint explodes. That is why physics engines separate rendering from physics, run physics with a fixed dt, and adjust the number of steps by the leftover time. Instead of making dt large, they run several steps.

Another is multiplying the velocity by 0.99 at every step to imitate damping. It is simple and does actually help stability, but the amount of damping depends on dt, so objects move differently on machines with different frame rates. The physically correct method is to put damping in as a force.

Finally, there is one practical rule about execution order. Within a physics step, the order of applying forces, updating velocity, solving collisions and updating position must be fixed, and if you do that order slightly differently in several places in the code, it cannot be reproduced. A simulation where the same input does not give the same result becomes almost impossible to debug — because you cannot reproduce the bug. When the server and client of a networked game must do the same computation, this reproducibility becomes an outright requirement.

And the practical criterion for choosing an integrator is this. In cases like games, where it only needs to look plausible and must run for a long time, semi-implicit Euler is almost always the right answer. This is because not diverging matters far more than the values being accurate. On the other hand, where the numbers themselves are the result, such as orbit computation or molecular dynamics, you use Verlet or a better method.

What you will do in the next lab

You run the same spring for 400 steps with three integrators and save each one's energy as CSV, draw the three curves on one PNG, and see with your own eyes that only Euler shoots upward. Next, you vary dt and check whether the energy growth rate matches the closed-form expression (1 + dt²)^n, and finally you put damping in as a force and see the energy decrease monotonically.