Whitelist more functions for Parallel Lua

As a Roblox developer, I’ve been working on multiple systems that could use quite a few more whitelisted functions that could potentially be thread-safe if looked into. Some of the hierarchies I’ve been working on and have been moving to be multi threaded include: server-side anti-cheat systems, hit box detection, rag doll systems, custom projectiles and global environment destruction. Since a large variety of functions aren’t currently marked as thread-safe I have to slow down tasks by constantly synchronizing and de-synchronizing them which defeats the point of performant and efficient multi-threading.

The following functions, at least to me, seem like they could potentially be multi-thread safe:

Model:GetExtentsSize (I use this a lot within the experiences I develop for)
Model:GetBoundingBox
BasePart:GetTouchingParts (I use this a lot within the experiences I develop for)
WorldRoot:ArePartsTouchingOthers

EDIT As of 5/31/2023 these functions have now been whitelisted: (Thank you whoever has been working on this)

PVInstance:GetPivot (EDIT: This has been whitelisted, last checked 5/31/2023)
Instance:GetActor (EDIT: This has been whitelisted, last checked 5/31/2023)
BasePart:GetNetworkOwner (EDIT: This has been whitelisted, last checked 5/31/2023)
BasePart:GetNetworkOwnershipAuto (EDIT: This has been whitelisted, last checked 5/31/2023)
BasePart:CanCollideWith (EDIT: This has been whitelisted, last checked 5/31/2023)
BasePart:GetVelocityAtPosition (EDIT: This has been whitelisted, last checked 5/31/2023)
Workspace:GetPhysicsThrottling (EDIT: This has been whitelisted, last checked 5/31/2023)
Workspace:GetNumAwakeParts (EDIT: This has been whitelisted, last checked 5/31/2023)
Workspace:GetServerTimeNow (EDIT: This has been whitelisted, last checked 5/31/2023)
Players:GetPlayerByUserId (This is not a web request) (EDIT: This has been whitelisted, last checked 5/31/2023)
Humanoid:GetStateEnabled (EDIT: This has been whitelisted, last checked 5/31/2023)
Humanoid:GetState (EDIT: This has been whitelisted, last checked 5/31/2023)
Player:GetNetworkPing (EDIT: This has been whitelisted, last checked 5/31/2023)

The use cases for most of these functions were listed at the top, such as, GetState, CanCollideWith and GetNetworkPing being used for a server-side anti cheat, ArePartsTouchingOthers for both hit box detection & anti cheat & environment destruction, GetNumAwakeParts and GetPhysicsThrottling for a projectile system and environment destruction (Custom version of throttling physics for BaseParts if the server physics is overloaded), GetNetworkOwner and GetVelocityAtPosition (Already had a similar thread: Allow GetVelocityAtPosition to be called in parallel ) for a rag doll system (Detecting if the client owns their own rag doll for server authoritative ownership of rag dolls and determining how far rag dolls should and have travelled) and so on. If at least some of these functions could be looked into being parallel safe, that would greatly help, even if all of them aren’t possible of being multi-thread safe.

18 Likes

I used TweenService:GetValue() in a parallel segment. I had to force it to run in serial because the method is not safe to use in parallel (though stuff is cached so it can still run in parallel most of the time).

I don’t see why that method would be unsafe to use in parallel

Bumping this, because I’m not allowed to post my own requests and this is the closest topic to my subject.

We need the ability to write to properties in parallel. If it breaks something, well, that’s our own fault and we can fix it individually. I have many different places I have been trying to use Actors and Parallel Lua, and every single one involves some sort of property change (afterall, why else would you script things in the first place, if not to change the world around the player?). This means I have not a single use case where I can actually optimize with Parallel (which has stopped a project dead in its tracks… literally, because it’s train related).

One example is a sound script. Essentially, it will get the Magnitude of the AssemblyLinearVelocity of a part, and pitch a wheel rolling audio based on the speed it’s moving. There are several hundred of these loops running in the game, and it would be absolutely wonderful if these could be split up into Actors. Afterall, they are literally the only scripts touching these sound instances.

Nope, not allowed…

3 Likes

If all a Script is doing is adjusting the Volume of a Sound based on the Velocity of a part, then Parallel Luau will not help with performance. There are inherent, significant costs that outweigh reading a property, doing a few multiplications and setting another property by several orders of magnitude.

To do so, it needs to re-synchronize, which involves stopping everything it is doing and waiting for the actual Datamodel to also finish whatever task it is on, which is horribly inefficient if you’re only updating a single property. In fact, it would probably be better to wait until every property has had it’s value calculated and assigned before re-synchronizing to actually set them… which you can already do by providing your Actor scripts with the relevant values and having them return a list of values back, and then setting them in a synchronized Script to ensure no loss of efficiency, but that will probably still be slower than just not being parallel at all because transferring data between threads has it’s own overhead and it likely isn’t worth it for such a simple operation.

Multithreading is complicated and difficult and should be used with intent and understanding, not throwing it at everything in the hopes of increasing performance. However, if you want to multithread something like this to see if it helps performance, there have been some signs that the engine will eventually allow writing to any property, as long as the Script and the Target are owned by the same Actor.

Unfortunately, memory corruption and race-conditions can be neither easy to identify nor fix. I’m not sure what you’re idea of “breakage” is, but mine are random crashes in completely unrelated places because that’s usually the result of memory corruption. No game engine should put that weight on the developer.

I hope these are not in their own individual Scripts

It’s speculation about the LuaCharacterController, whether Actor for OPTIONAL LuaCharacterController are going to stay or not, is another question.

Just keep in mind that LocalScripts aren’t affected. Unsure about Server Local Scripts, never tested.

1 Like

This is the problem, and why I cannot use it.

This is 100% what is necessary, and hopefully they push this in the future.

Well, yeah, there really isn’t any other way to do it. The only other option is to have one master script cycle through every single part that needs this calculation done, and that has shown through testing to have the same exact performance impacts as everything else (same calculations, different organization).

1 Like

Generally you want to reduce the number of Scripts you have because each Script has it’s own coroutine (meaning that the Scheduler has more work switching between Scripts) and takes up memory overhead as an instance that you don’t need to have with just one Script. It might not measurably improve performance or memory footprint, though, but I think it’s good practice given the above.

There’s stuff on UserInputService that seem like it could really be whitelisted
namely:

GamepadSupports
GetConnectedGamepads
GetDeviceAcceleration
GetDeviceGravity
GetDeviceRotation
GetFocusedTextBox
GetGamepadConnected
GetGamepadState
GetKeysPressed
GetLastInputType
GetMouseButtonsPressed
GetMouseDelta
GetMouseLocation
GetNavigationGamepads
GetStringForKeyCode
GetSupportedGamepadKeyCodes
IsGamepadButtonDown
IsKeyDown
IsMouseButtonPressed
IsNavigationGamepad

idk if it’s just an issue with documentation, but none of the methods in UserInputService have tag(s)
according to the documentation, that means it’s not safe to use in parallel by default
and because of that, according to the documentation, all of the UserInputService methods are not safe to use in parallel.
I find that hard to believe, but just in case, I’m going to point that out here.