AlarmClock - Wake up sleeping BaseParts and prevent Sleep

The Problem

The Roblox physics engine will try to intelligently put parts to “sleep” whenever possible, meaning they aren’t being physically simulated. The is obviously a very important optimization, since otherwise you’d be simulating thousands of parts at all times.

However, sometimes it gets it wrong, as seen in this clip from @BanTech’s bowling game. The pins are sitting still, so the engine puts them to sleep- then a speeding ball hits them and they don’t move at all.

In a project of mine, players can move boxes around, and putting the box onto an elevator would put it to sleep and the elevator would leave it behind!

Roblox hasn’t (yet?) given us any API to manually flag parts as active, so I came up with a clever trick to keep parts awake and then wrote a module that wraps it up neatly and efficiently.

You should definitely go support this feature request so that we can get this feature added first party with less overhead.


The Solution

To keep parts awake at minimal performance cost, I determined that the best way is to softly push the object towards the ground. We only push it when the Velocity is 0,0,0 as any other velocity means it must already be awake. We push it gently down, because if it’s asleep then it must be resting on something so a downward velocity has almost no risk of actually causing the part to move- just wakes it up. This method is used in production environments by BanTech, EgoMoose, Firebrand1, and more, so I know it works well and has been battle tested.

As you can see, I’ve told it to keep all the parts awake at all times, so they’re awake even when completely unmoving. (Awake parts are highlighted in red)


The API

function AlarmClock:ForbidSleep(Part)

Keeps the given Part awake at all times.

function AlarmClock:ForbidSleepForDuration(Part, Duration)

Keeps the given Part awake for the given Duration.

function AlarmClock:AllowSleep(Part)

Allows the given Part to fall asleep (aka removing it from our forbidden list).

function AlarmClock:AllowAllSleep()

Allows all our currently forbidden parts to fall asleep (aka clearing our forbidden list).


Source

133 Likes

Update

Added protection against user error

Added parameter validation and ancestrychanged connections to prevent users from accidentally leaking memory or causing errors.

11 Likes

ForbidSleep sounds like some torture to me :joy:
Great job on the module, I’ve had issues with this previously, and can now finally continue on those projects!

30 Likes

Thanks so much, this allowed me to continue working on my project that relies on parts not going to sleep. Weirdly, parts go to sleep even if they have some smallish angular velocity, which makes my spaceship controls not work as intended / in a realistic way.

I only had to change it to apply the force in a random direction every frame to prevent the small force from accumulating over time since my game doesn’t have gravity.

Unfortunately only regulars can comment on feature request threads, so if someone wants to post a link there to this comment, it might notify Roblox staff of another use case for a physics sleep API.

1 Like

What is this meant for? The code nullifies using it against instances…

Man I love relying on hacks because Roblox wont give us basic APIs to wake up parts

6 Likes

I looped through all the parts in a model I wanted to keep awake at all times, but my model is still freezing. The model is located in workspace, the module is located in replicatedstorage, and a serverscript is accessing the module.
image

Great Resource! but how would I know if the part is awake or asleep?

Go to studio setting > physics > Display > the check the “Are Awake Parts Highlighted” box.

1 Like

I never even knew parts sleeping was a thing. Pretty useful though.

1 Like

Why on earth does this have to exist? Why, when searching for a solution to parts going into sleep, is this all I get? I’m not even convinced this would work, since I’m currently having parts with AlignPositions moving at 0.1-0.2 studs per second getting put into sleep mode by roblox. Even adding rotation velocity doesn’t seem to fix it, must I really be constantly wasting system resources loop-moving parts to make them not fall asleep?

What is the point of a physics system if it refuses to do any physics?
This really should be a mixture of bug reports and feature requests, it’s embarrassing on roblox’s end that someone had to make a system to try to circumvent an obvious design flaw in roblox.

7 Likes