How to Add Custom Properties to a Matter.js Body
You can assign custom physical and non-physical properties to a Matter.js body object. Because Matter.js bodies are standard JavaScript objects, the library allows developers to attach custom data directly during initialization or dynamically at runtime. This article explains how to define these custom properties, access them during simulation events, and utilize them to drive custom physics behaviors like health, buoyancy, or unique collision responses.
Assigning Properties at Creation
The most straightforward way to add custom properties is by passing
them directly into the body's options object when calling factory
methods such as Bodies.rectangle,
Bodies.circle, or Body.create.
const playerBody = Matter.Bodies.rectangle(100, 100, 50, 50, {
density: 0.002,
restitution: 0.5,
// Custom properties
health: 100,
damageMultiplier: 1.5,
isInvulnerable: false
});Matter.js copies any additional key-value pairs provided in the configuration object directly onto the created body instance.
Assigning Properties Dynamically
You can also assign, modify, or delete custom properties at any point during your game or simulation loop using standard JavaScript syntax:
// Adding a new property dynamically
playerBody.currentBuff = 'speedBoost';
// Updating an existing property
playerBody.health -= 25;Using Custom Properties in Collision Events
Custom properties are especially useful during collision detection.
When handling events via Matter.Events, you can inspect
each body's custom attributes to determine how objects should
interact.
Matter.Events.on(engine, 'collisionStart', (event) => {
const pairs = event.pairs;
for (let i = 0; i < pairs.length; i++) {
const { bodyA, bodyB } = pairs[i];
// Check if one of the bodies has a custom 'damageMultiplier'
if (bodyA.damageMultiplier && bodyB.health) {
bodyB.health -= 10 * bodyA.damageMultiplier;
} else if (bodyB.damageMultiplier && bodyA.health) {
bodyA.health -= 10 * bodyB.damageMultiplier;
}
}
});Simulating Custom Physical Behaviors
Matter.js handles built-in physics such as gravity, friction, and restitution automatically. If you define a custom physical property—such as aerodynamic drag, lift, or buoyancy—you must implement the logic to apply forces manually using the engine's update loop:
Matter.Events.on(engine, 'beforeUpdate', () => {
const bodies = Matter.Composite.allBodies(engine.world);
bodies.forEach((body) => {
// Custom buoyancy property
if (body.buoyancy) {
const upwardForce = { x: 0, y: -body.buoyancy };
Matter.Body.applyForce(body, body.position, upwardForce);
}
});
});Best Practices
- Avoid Overwriting Core Properties: Do not use
custom names that conflict with internal Matter.js properties such as
mass,friction,velocity,position, orisStatic. - Use a Dedicated Namespace: To keep custom data
organized and prevent accidental overwrites, group custom attributes
under a single namespace object (e.g.,
body.customData = { health: 100, isFloating: true };). - Matter.js Plugin Support: If building reusable
tools or modules, you can place custom data within the official
body.pluginobject to avoid interfering with other libraries.