Verlet integration is a numerical method used to integrate Newton’s equations of motion. In gamedev, it is the “secret weapon” for stable physics simulations involving constraints like ropes, cloth, or bridges.
Most beginners use Euler Integration:
pos += velocity * dt
velocity += acceleration * dt
The problem? Euler accumulates error quickly. If a rope is pulled tight, the velocity can become massive, causing the simulation to “explode.”
Verlet Integration is different—it doesn’t store velocity at all. It calculates motion based on the Current Position and the Previous Position.
next_pos = pos + (pos - prev_pos) + acceleration * (dt * dt)
Think of it as the object “remembering” where it was. The difference between pos and prev_pos implicitly acts as the velocity. This makes it incredibly stable for objects under tension.
public class VerletPoint {
public Vector2 position;
public Vector2 prevPosition;
public Vector2 acceleration;
public void Update(float dt) {
// (position - prevPosition) is effectively our velocity
Vector2 velocity = position - prevPosition;
prevPosition = position;
position = position + velocity + acceleration * (dt * dt);
// Reset acceleration for the next frame
acceleration = Vector2.zero;
}
}
The true power of Verlet is how it handles constraints (e.g., a stick connecting two points). Instead of calculating forces, you simply move the points until the distance between them is correct.
void SatisfyConstraint(VerletPoint a, VerletPoint b, float targetDist) {
Vector2 diff = a.position - b.position;
float dist = diff.magnitude;
float fraction = (targetDist - dist) / dist / 2f;
Vector2 offset = diff * fraction;
a.position += offset;
b.position -= offset;
}
If you run this constraint check 5-10 times per frame, the rope becomes “stiffer.”
prevPosition instead of velocity.