Matter : Optimize (sleep ?)

Hello,

I would like to optimize the physics Matter in my game. I activated “enableSleeping”. This greatly optimizes my game!
Except I have a problem. I have certain objects that do not move. They therefore become isSleeping = true.
As a result, no collision event is dispatched with them …

I told myself that I could deactivate “enableSleeping” all x frames. Or then deactivate it only on certain elements? But I do not know how…

Do you have any ideas or solutions please?

I’m not familiar with matter physics though can you not apply the sleeping to individual game objects? Or can it only be added to the entire scene.

If not could you detect when these game objects overlap (not collide). Then enable it?

Hello !

Thank you for your answer. It does not seem to me (at least I have not found) that sleep mode can be activated / deactivated only for certain elements.

Your idea to check if there is overlap is a good idea, but would mean doing a calculation every x frames on all the objects concerned … Not ideal for performance!

You inspired me with an idea: It would seem when modifying the velocity manually and in a minimal way (x: 0.0001), that is enough to wake up the object. And I noticed that if another moving object collides with it, then it wakes up (even if it hasn’t moved).

Only problem now is that I have several objects sleeping in (“rooms” which are next to each other). And I have to test if they are in contact on their sides. Since the rooms will never move (they have no body, only sensors), they will go to sleep and never check if they touch … Any idea?

I’m actually out of ideas on this one however, if you could throw together a quick example in code sand box or stackblitz I can take a second look - others might find it easier too.

You can control the sleeping for objects. There are a couple of things that can be done and you need to pay a bit of attention to when and how you do it.

If you want to disable sleep for an object always:
When creating it, set the matter body.sleepThreshold = -1 this will disable the default sleep ticker of 60 (meaning 60 updates of no/little movement and object sleeps). -1 will make it never sleep, you can also tweak this to have a higher value to make it take longer until object sleeps.

If you want to reset a sleeping object to not sleeping:
Phaser.Physics.Matter.Matter.Sleeping.set(matterBody, false);
This will set a body to not sleeping, but it will go back to sleeping depening on the value of body.sleepThreshold.

If you want to change sleepThreshold while object active:
body.sleepThreshold = VALUE;
Phaser.Physics.Matter.Matter.Sleeping.set(matterBody, TRUE/FALSE);
Only changing the sleepThreshold might not always work, toggling the sleeping makes sure the change you set works.

Depending on type of game and type of objects you can use these in various ways to fix sleep issues. For my current project I have some objects that had a tendency to get stuck in mid-air with sleep, so I fixed it by checking if they are in the screen and if they are they will not sleep.

2 Likes

Hello !
Thank you for your very complete answer!

This is exactly what I needed!

Some details all the same:
this.sensor.sleepThreshold = -1
Phaser.Physics.Matter.Matter.Sleeping.set (this.sensor, false)

I did this, actually it comes out of sleep, but the sleepThreshold does not seem to be taken into account … It returns to sleep after a few seconds … Yet with each movement of the mouse I force him to wake up.

Do you have an idea ?

Can you also explain to me how you do to verify that the object is displayed in the camera please? I am looking for a code for that in an optimized way (it should not consume more fps than it saves.)

Hey,

First, I remembered you can simplify Phaser.Physics.Matter.Matter.Sleeping.set and instead simply set this.sensor.body.isSleeping = false; I forgot that you had access to it that way as well. I can’t recall that Sleeping.set() does anything more than setting the property, so should work the same either way.

Not sure about why it wakes up. When I tested by:

let player = this.matter.add.sprite(X, Y, "KEY", "FRAME")

setInterval(() => console.log(player.body.isSleeping),100);

setTimeout(() => {
    player.body.sleepThreshold = -1;
    player.body.isSleeping = false;
}, 5000);

It starts awake, goes to sleep after a few seconds, then is set back to awake after 5 seconds and stays awake. If I remove sleepThreshold it will only flick back to awake before sleeping again. I have not actually tested if it physically behaves correct though.

You can also be blunt about it and set body.isSleeping true/false in the update loop of the object depending on when you want it to do either.

You can check if an object is in the camera view in a few ways, I think this is the easiest solution (code snippet assume you are in the object class that wants to check if it is visible):

let camView =this.scene.cameras.main.worldView;

if(camView.contains(this.x, this.y)){
    // Make sure object is not sleeping
}

You can for example put this in a timer that runs every 1-2 seconds.

Thank you very much for all these precisions !

Hello !

I updated Phaser to 3.23, I don’t know if it’s related to that, but some of my bodies no longer fit into isSleeping.

I created a “mining” system. When you mine a tile with a resource, it turns into a Matter Sprite.

Normally, once the “resource” has fallen into its new zone, and touches the collider below, it should enter sleep mode (and have an alpha of 0.3). But this is no longer the case. She never sleeps, like she’s still moving …

Here’s a video to show you:

Here is my code when creating a new resource:
this.sprite = this.scene.matter.add.sprite(x + this.getRandomIntInclusive(15, 49), y, type, 0).setDisplaySize(32, 32).setFixedRotation(true);

this.sprite.setCollidesWith([ 1 ]);
this.sprite.setCollisionCategory(4);
this.sprite.setSleepStartEvent(true)

if(this.getRandomIntInclusive(1, 2) == 2)
  this.sprite.setFlipX(true)

Do you have an idea ?

EDIT :
I have just seen that the sleeping of objects is quite random. I don’t know if it’s relative to the quantity of matter objects or if it’s really random.

I have the impression that after a while, if there are too many objects, the old ones sleep but the new ones never sleep.

I even had the case where an object does not go to sleep, but if I move the camera and put it out of the field of vision, it goes to sleep.

And actually going back to 3.21 I no longer have the problem.

1 Like

Hey!
Possibly it is as simple as that 3.22 is a HUGE update for Matter in Phaser and I think it includes changes to the config for matter when you create a new phaser game instance.

It could be that you need to change how your config looks for when you set phaser to use Matter and what settings to use. For example the debug option for showing sleeping is false by default and I am not sure it is an alpha change, could be debug is changed to a color change in the collider as default.

This is how my physics section looks like in my config:

physics: {
    default: "matter",
    matter: {
        debug: {
            showSleeping: true
        },
    enableSleeping: true
    }
}

I tested this example: https://labs.phaser.io/view.html?src=src\physics\matterjs\sleep%20events.js and it is working fine in both 3.23 and 3.21. I also tried in my own game (running 3.23) and I could not notice any problems. I however do not have more than 20 or so dynamic objects on screen at a time.

If you can’t find any problem with the config, make sure to check the log when running the game for any matter messages and also to do your own print of the isSleeping value to rule out any error being with the debug info and not with the actual behaviour.

Hello

I just tested by going back to 3.23.

I consulted the doc concerning the debug options.

Indeed, there are quite a few!

I see that the body statics go well in sleep (their alpha goes down). But bodies with gravity never fall asleep.

No console errors. I log every second the isSleeping of my bodies before sleeping. It is always false.

It’s very strange…

I will go back to 3.21 everything works well and in an optimized way.

What does 3.22 and 3.23 bring? Are there real performance optimizations?

No performance improvements that I can recall. Staying with 3.21 should be a good solution.

Release notes for 3.22 here: