Summary
An issue that has persisted in our games involves the PrismaticConstraint. In our games, this is used to control train doors opening and closing (via sliding). Under normal circumstances, meaning most of the time, the PrismaticConstraint functions properly and fully opens and closes the door on trains.
However, in some cases, PrismaticConstraint fails to fully close the door, leaving a gap, until the train is moved. Moving the train even slightly causes it to close the door properly. The cause of this issue is unknown to me.
Reproduction Steps
PrismaticConstraint set to an Attachment in door and Attachment in wall. Both are unanchored as they are part of a moving train
PrismaticConstraint value set to number to have the door close.
Expected Result
PrismaticConstraint should move the door part as it should, which it does most of the time.
Actual Result
Sometimes, PrismaticConstraint fails to fully move the door part.
This bug is still occurring and it is very annoying. Our players do not like it. I am even experiencing this in Roblox Studio on a simple baseplate. I would appreciate a response to this.
Hi! Sorry for the late reply, this bug report was assigned incorrectly.
I already have one of your train models that you provided to help track down this bug. I’m going to try to reproduce with that model, I’ll let you know what I find.
Thanks for the reply! Let me know if you need game links as well, since I realized I forgot to provide that. They’re the same games as the other bug, though.
My suspicion is that the doors are “going to sleep” before they can fully close. When parts are moving “slow enough” that they are essentially not moving, the physics engine puts them to sleep to improve performance (see this post for a more detailed description). The sleep system includes a set of velocity tolerances. If a part is moving below the velocity tolerance, it is considered not moving, and goes to sleep.
To see when parts are asleep or awake in Roblox Studio, you can go to File → Studio Settings → Are Awake Parts Highlighted. You mentioned that you were able to reproduce this issue on a simple baseplate. Do you happen to have that repro file?
If this behavior is in fact caused by the sleep system, the simplest fix is to simply use a higher servo speed to ensure that all parts are moving faster than the velocity threshold. I noticed in the place file that you provided before, the Speed used to close the doors is lower than the value used to open the doors (1.2 studs/sec vs 2 studs/sec). It would be worth increasing the closing Speed to see if that mitigates the issue.
I see. What’s the reason for the prismatics in the doors correcting themselves once the train starts moving? That’s what usually happens.
Additionally, I don’t want to have to change the speed of the prismatic constraint because the speeds that they are set to are on purpose and are intended that way in our games (the timing of the door opening and closing). Is there anything else I can do?
What’s the reason for the prismatics in the doors correcting themselves once the train starts moving?
Great question! Once the train starts moving, it wakes up the doors, which wakes up the PrismaticConstraint, allowing it to close the doors fully. The Roblox Engine automatically wakes up parts if any of their neighboring parts (parts connected via constraints) are moving fast enough.
A general fix that avoids increasing the Speed would be to check if the doors fully closed (by checking the CurrentPosition of the PrismaticConstraint ). If they haven’t closed fully, you can “wake them up” by disabling and re-enabling the PrismaticConstraint .
We are currently putting together documentation of the sleep system on our Creator Hub, stay tuned!
Forgive me butting in, but are you sure this is not something that Roblox should be providing better control over in the first place? This seems like a prime target for a Part::ForceStayAwake function or similar (either that, or improvements to the sleep system itself).
Great question! This is something we debate constantly on the physics team. On the one hand, providing fine-grained control of which parts can sleep would easily solve issues like these. However, the potential loss in performance could be substantial. For example, if developers don’t allow any parts to fall asleep (even when the parts aren’t moving), there would be a large impact on performance since all parts would always be simulated.
That said, we are looking into potential improvements to the sleep system to improve its ability to differentiate between moving and non-moving parts. As described in this post, we will always need to use some small tolerance to determine if parts are awake, so parts that are moving “slow enough” will always go to sleep.
With all respect, I don’t understand that viewpoint. Roblox’s developers are not children anymore. We understand why the sleep system exists and the performance implications of disabling it on parts. There’s cases where disabling it on specific parts for specific amounts of time is useful (as shown by this thread and others), and a mindful developer would use them properly, when needed, just like every other thing in the engine that may have a performance impact.
Yes, an inexperienced developer may make the mistake of spamming “keep-alive” on every single part in the game, but they may also make the mistake of using too many transparent parts, or too many meshes, or too many decals, etc. etc. They would make such a mistake, learn from it, and not do it again, and an experienced dev (especially one focused on physics-based games) wouldn’t make it in the first place. They use the tool for what it’s made for. In exchange, those whose games are suffering from the sleep system miscategorizing their parts don’t suffer anymore.
I really hope your team reconsiders this viewpoint, especially when other sections of Roblox have been on a roll with giving their devs more control recently. (My personal highlights include the new Audio API, buffers, and EditableImage/Mesh.)
Absolutely, this is an active topic of discussion on the team and nothing is set in stone. In the short term, I hope that providing better documentation of the sleep system will help developers achieve their desired behavior.
@Real_BenTheMiner were you able to implement any of the fixes suggested? Would love to see the results!
Yes, disabling and enabling the constraint appears to work! However, a simple wait after the doors start to close isn’t enough for my game, especially since server lag can make constraints move slower than they should, so I’ll have to make changes with this in mind.
Hey, I’ve finally been able to try this out in-game. Unfortunately, the method of disabling and enabling the constraint doesn’t seem to work! I’m not sure why, considering it worked before…
That’s surprising that the behavior changed, I don’t think we’ve changed anything on our end that would change this behavior.
Since the doors are getting stuck in an open position, I suggest checking the prismatic constraints CurrentPosition to check if they are open after some amount of time. You could bind a function to Runservice.Stepped that checks if the doors are still open and disables/enables the constraint to wake them.