Unintuitive Matter Physics "nextCategory" Behavior

I’ve got a gameplay scene where inside create() it makes a series of collision categories to be used:

this.playerOneCollision = this.matter.world.nextCategory();
this.playerTwoCollision = this.matter.world.nextCategory();
this.bulletCollision = this.matter.world.nextCategory();
this.collectableCollision = this.matter.world.nextCategory();
this.enemyCollision = this.matter.world.nextCategory();
this.groundCollision = this.matter.world.nextCategory();

Everything works exactly as described in the documentation, but after I restart the level six times, no collisions work anymore, and everything just falls through the floor into oblivion.

After hours, I tracked down the issue: the call “this.matter.world.nextCategory()” returns a bit flag – specifically, it returns the next bit flag available since the last time you called “this.matter.world.nextCategory();”. The first call returns 1, then next is 2, then 4, then 8, etc etc, until eventually it returns 2^31. Past that, something goes wrong and all subsequent collisions will fail. My assumption is that the engine is working with a 4 byte integer for the “next category”, and that the 32nd call overruns the bit count.

Regardless, my solution was to manually assign power-of-two bit flags to my collision categories:

this.playerOneCollision = 1;
this.playerTwoCollision = 2;
this.bulletCollision = 4;
this.collectableCollision = 8;
this.enemyCollision = 16;
this.groundCollision = 32;

There may be a way to properly reset the “next category” integer that I didn’t see in the documentation or the sample apps, but my solution seems to work ok. Anyway, I figured I’d share just in case someone else runs into this, so they don’t waste a few hours like I did.

this.matter.world.resetCollisionIDs() may work.

1 Like

That’s the EXACT call I was missing. Thank you!

1 Like