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.
Thanks!
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).
Hi Mauio!
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.
Thanks!
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.)
Great points raised here. I’d love to see more control over this as well.
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!
Thanks
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.
A developer knows what the developer needs best. If I want to disable physics sleeping on a specific part or set of parts from the default, there’s a good reason for it. I shouldn’t have to use workarounds for an engine feature that should be toggleable on a granular per-part basis to begin with because of some convoluted reason like “maybe you don’t understand how game engines work”…
True! I would love for there to be a feature to just disable the sleeping feature for these specific constraints, since these are the only constraints I have this issue with.
Something interesting that was noticed: the constraints get stuck as already known, but upon exiting the vehicle seat of the train, the constraints move and the doors close! (Notice the close sound after I hop out)
Well, I just said that disabling and enabling the constraint didn’t actually fix it. I also tried continuously doing it every 0.3 second or so while the door was closing and it still didn’t help.
My guess is that your character touching the doors is waking them up and allowing them to close fully.
One way to debug what’s going on is to turn on sleep state visualization. In Studio Settings, select the “Are Awake Parts Highlighted” option to see what parts are awake and asleep. Awake parts will have a red border, and asleep parts will have no border or an orange border. It’s possible that you’ll need to set a larger Velocity for the prismatic to get it to close, since the doors may be going right back to sleep when they open.
We are looking into other ways to improve the sleep system that would likely help in this situation. For example, we could add a check of a servo’s CurrentPosition
and TargetPosition
to determine if the parts should sleep.
Thanks
My character isn’t touching the doors, all I did was hop out of the vehicle seat and it makes the doors close.
How can I set a larger velocity?
Oh, got it. Jumping in and out of VehicleSeat
will wake the assembly that it’s welded to, so it makes sense that the doors would wake and finish closing.
You can change the velocity that the doors move by setting the Speed
property of the PrismaticConstraint
. You may also want to increase the LinearResponsiveness
and the ServoMaxForce
.
Was able to find a workaround that was perfect for what we were doing (setting the target position to be after the actual target, and then setting it to the actual target).