Concept
Erosion is a physics simulation of a rocky mesa breaking apart under falling debris. The idea came from thinking about how landscapes that look permanent are always being shaped by small, repeated impacts over time. I wanted to use Matter.js not just to show objects falling but to model a process. The terrain starts whole and breaks down based on how hard things hit it.
Code I Am Proud Of
The collision event handler is the center of the piece. It does not react to every contact. It reads the speed of the incoming rock and only shatters a terrain block when the impact crosses a threshold. This makes the simulation feel grounded. Slow rocks bounce off. Fast rocks break things.
Events.on(engine, 'collisionStart', function(event) {
for (let pair of event.pairs) {
let { bodyA, bodyB } = pair;
let rock = null, ter = null;
if (bodyA.label === 'rock' && bodyB.label === 'terrain') { rock = bodyA; ter = bodyB; }
if (bodyB.label === 'rock' && bodyA.label === 'terrain') { rock = bodyB; ter = bodyA; }
if (rock && ter) {
let impactSpeed = Vector.magnitude(rock.velocity);
if (impactSpeed > 3.5) {
let idx = terrain.findIndex(t => t.body === ter && !t.broken);
if (idx !== -1) shatterTerrain(idx, impactSpeed);
}
}
}
});
I am also proud of the shatterTerrain function because it does three things at once when a block breaks. It triggers a screen shake scaled to the impact force, spawns a flash at the contact point, and sends out a burst of dust particles that drift upward and fade out. Each of those effects runs from the same impact speed value, so they all feel connected.
Embedded Sketch
Milestones and Challenges
The first milestone was drawing the terrain. I wrote a heightmap function that builds a mesa shape, peaks in the center, and slopes toward the edges, with small random offsets per column to roughen the silhouette. I added a sky gradient and a highlight strip on the top face of each block so the structure looked like real layered rock before any physics was involved.

The second milestone was loading that terrain into Matter.js as static bodies. Each block became a rectangle body placed at the correct position. Drawing them back from their body positions confirmed the physics world and the visual layer matched.

The third milestone was getting rocks to fall with physical variety. Rocks now vary in size, fall speed, bounciness, friction, and spin. Density scales with size so large boulders hit harder. Wind drifts slowly over time toward a random target every three seconds, and the visual rain streaks angle to match. This step exposed the first real challenge: collision filters. Without explicit category and mask values set on each body type, rocks passed straight through the terrain. Setting category: 0x0002 on terrain and mask: 0x0001 on terrain fixed which bodies could interact with which.

The fourth milestone was the full shattering system with visual feedback. When a collision event fires and the impact speed clears the threshold, the terrain block is removed, fragments spawn and tumble, dust particles burst outward, a flash appears at the contact point, and the canvas shakes. The main challenge here was performance. Without cleanup, thousands of fragment, dust, and rock bodies built up below the canvas over time and slowed the simulation. Adding a per-frame filter that removes any body or particle whose position exceeds the canvas height solved the problem completely.

Reflection
The piece works well as a slow process. Dropping one rock at a time and watching the terrain wear down has a satisfying quality. The storm mode makes the erosion visible in seconds and shows how the system handles high load. The wind system adds unpredictability without feeling random because it drifts gradually rather than jumping between values.
For future work I want to add water. Fragments that collect at the bottom could be slowly submerged as a rising water level fills the valleys left behind by the erosion. I also want to track how many blocks have been destroyed and show it as a live counter so the viewer has a sense of scale over the life of the simulation.
References
The Nature of Code, Chapter 6: Physics Libraries Matter.js documentation on collision events and body properties
This is a really strong project, especially in how you frame erosion as a process rather than a visual effect. The idea of gradual breakdown through repeated impact comes through clearly, and the system feels grounded because of how you tie destruction directly to impact speed. The collision threshold is a particularly effective decision, as it introduces logic and restraint, making the simulation feel less arbitrary.
What stands out most is how you connect physics and visual feedback. The fact that screen shake, flash, and dust all derive from the same impact value creates a cohesive response, where everything feels part of the same event rather than layered effects. This gives the system a strong sense of physicality.
The progression of milestones is also clear and well structured. You move from building the terrain, to introducing physics, to adding variation and feedback, and finally to optimization. The performance issue and your solution are especially important, as they show an awareness of how systems behave over time, not just at the moment of interaction.
One area you could push further is the idea of time and accumulation. While erosion is present, it might be interesting to make its long-term effects more legible. For example, could the terrain visually record where the most impact has happened, or could there be a clearer sense of before and after? This could strengthen the conceptual focus on erosion as a slow, transformative process.
I really like how this project focuses on a process rather than just a visual effect. Watching the terrain slowly break down over time makes it feel much more meaningful than just objects falling and colliding.
The impact-based shattering works really well. The fact that only high-speed collisions break the terrain makes everything feel more realistic, and it adds a sense of cause and effect. It’s also nice how all the visual feedback like screen shake, flash, and dust are tied to the same impact value, so it all feels connected.
The variation in the rocks and the addition of wind also stood out. It keeps the simulation from feeling repetitive and adds a bit of unpredictability without making it chaotic.
If anything, adding something like the water system you mentioned could push the idea even further by showing a longer-term transformation of the landscape. But overall, I believe this is a really well done project!