What happens to planck.js position vectors with NaN?
Feeding NaN (Not-a-Number) values into a planck.js
position vector breaks the underlying physics simulation, causing
computational failures, invisible or disappearing bodies, and cascading
errors across the physics world. This article explores how planck.js
handles NaN inputs, why it leads to silent failures, and
how you can prevent it from ruining your 2D physics simulations.
How planck.js Reacts to NaN Values
Planck.js is a JavaScript port of the Box2D physics engine. It relies
heavily on continuous mathematical calculations for linear algebra,
collision detection, and constraint solving. When a NaN
value is introduced into a position vector (such as
Vec2(NaN, 5) or via body.setPosition()), the
engine does not typically throw an immediate runtime error. Instead, it
fails silently and propagates through the system.
- Cascading Failures: In JavaScript, any mathematical
operation involving
NaNresults inNaN(e.g., \(5 + \text{NaN} = \text{NaN}\)). Once a position vector containsNaN, every subsequent velocity, acceleration, and distance calculation involving that body also becomesNaN. - The “Disappearing Body” Phenomenon: When the
collision detection system processes a
NaNposition, the bounding box (AABB) calculation fails. As a result, the body will instantly vanish from the rendered screen and stop colliding with any other objects in the world. - Broad-phase Pollution: In severe cases, the
NaNvalue can corrupt the engine’s dynamic tree (the structure used to optimize collision checks). This can cause the entire physics simulation to freeze or behave erratically, affecting otherwise healthy bodies.
Common Causes of NaN in Physics Vectors
NaN values rarely appear out of nowhere; they are
usually the result of upstream coding logic flaws before the data is
passed to planck.js.
- Division by Zero: Calculating a trajectory or normalizing a vector with a length of zero (e.g., trying to find the direction between two objects that are exactly on top of each other).
- Undefined Variables: Accidentally passing an
uninitialized variable or a typo in a property name into the
Vec2constructor. - Invalid Math Operations: Performing operations like
Math.sqrt(-1)or parsing a corrupted state string viaparseFloat()before applying the result to a physics body.
How to Prevent and Debug NaN Errors
Because planck.js fails silently, debugging NaN issues
can be incredibly frustrating. The best defense is proactive
validation.
- Sanitize Inputs: Always validate external forces,
user inputs, or complex math results before updating a planck.js vector.
You can use JavaScript’s built-in
Number.isNaN()function. - Implement a Vector Guard: Create a helper utility
to safely generate planck.js vectors, fallback to a safe default if
NaNis detected, or throw an explicit error early so you can trace the exact line of code causing the bug.
function createSafeVec2(x, y) {
if (Number.isNaN(x) || Number.isNaN(y)) {
console.error("Warning: NaN detected in vector initialization!");
return planck.Vec2(0, 0); // Safe fallback
}
return planck.Vec2(x, y);
}