Collision math divides by mass constantly, and a wall has effectively infinite mass, so engines store one over the mass instead. Today you compute inverse mass, where a mass of zero means immovable.
Store a body's inverse mass, defined so that a mass of zero yields an inverse mass of zero.
Collision response is full of divisions by mass, and doing them as multiplications by
a stored inverse mass is both faster and, more importantly, lets you represent an
immovable body cleanly. A wall or the ground should never budge no matter what
hits it - that is a body of infinite mass, and 1 / infinity is 0. So the
convention is: a mass of 0 is a special marker meaning infinite mass, and its
inverse mass is 0. Multiplying any impulse by that zero inverse mass produces no
change in velocity, which is exactly what “immovable” means.
Set both together through SetMass so they never drift out of sync. While you are
here, add a Restitution field - a number from 0 to 1 for how bouncy the
body is, 0 for a dead thud and 1 for a perfect bounce. It just rides along as
data today; the resolution chapter is where it earns its keep. The next lesson uses
this zero inverse mass to make a static body ignore forces entirely.
// add InvMass float64 and Restitution float64 fields to Bodyfunc (b *Body) SetMass(m float64) {b.Mass = mif m == 0 {b.InvMass = 0 // infinite mass: a static, immovable body} else {b.InvMass = 1 / m}}