So, Microsoft changed a bunch of floating point code to remove bugs and increase accuracy ( https://learn.microsoft.com/en-us/cpp/porting/floating-point-migration-issues?view=msvc-170 ), and this update breaks Bullet when using /fp:fast (specifically it breaks BulletDynamics constraint solver). Modifying my project, I was able to narrow the issue down to the constraint solver - specifically the issue (explosion of absurdly high collision forces) happens when you have either a closed loop of constraints/collisions (eg: tank tread, a character holding an item in both hands, two characters hitting each other with attacks at the same time) or just a long enough chain of constraints (eg rope). I'm guessing the core of the problem is some combo of SSE instructions used to return exactly 0 or below 1.0 and now due to the new math it's not quite 0, or multiplies in a scalar that's now over 1 instead of under? I haven't figured out the exact issue, but I did find that changing my /fp flag to /fp:precise, /fp:strict, or /fp:default fixes the behavior but unfortunately I lose some optimization.