Description:
If a script from StarterPlayerScripts starts running in a player’s PlayerScripts, and then immediately removes a member of StarterPlayerScripts (i.e. itself), this can cause the ControlScript (or other scripts?) to not be copied over to the PlayerScripts. This breaks player movement completely unexpectedly.
Minimal repro:
See the following baseplate with 1 script:
StarterPlayerScripts_ControlBroken_Repro.rbxl (12.6 KB)
The only code in this file is in game.StarterPlayer.StarterPlayerScripts.Test:
It has the following contents:
-- this script finds itself in StarterPlayerScripts:
local StarterPlayer = game:GetService("StarterPlayer")
local StarterPlayerScripts = StarterPlayer:FindFirstChildOfClass("StarterPlayerScripts")
local test = StarterPlayerScripts:FindFirstChild(script.Name)
print(test:GetFullName()) --> StarterPlayer.StarterPlayerScripts.Test
if test then
-- destroys StarterPlayer.StarterPlayerScripts.Test
test:Destroy()
end
-- now, ControlScript is not copied over to the player scripts
When you press Play or Test Server+Player in this file, the player’s controls are broken (player is stuck in place), yet the script never touches the ControlScript. ControlScript is still in StarterPlayerScripts (and Test is gone from StarterPlayerScripts, as expected), but the ControlScript was never copied over to PlayerScripts.
This can be seen here in the game hierarchy when the game is running:
Further details:
This bug happens 100% of the time (as far as I can tell after trying 20-30 times) when running the minimal repro (on Win10 Pro, Studio version 0.318.0.168780).
When a yield is added before running the script (i.e. putting wait(5) at the top), the bug does not occur.
As I am not touching the ControlScript at all, I suspect one reason for this happening is that when the scripts are being copied over from StarterPlayerScripts to PlayerScripts, some kind of counter is used to determine when all scripts have been copied. Perhaps ControlScript is the last in line to be copied, and therefore isn’t copied over since the game determines there are four scripts in each directory already.
I’m not sure when this bug started happening first. I noticed it today because I implemented something similar in my game to reduce clutter in PlayerScripts and to remove a potential exploiting entrypoint, and it turned out breaking character control unexpectedly.