Copy local script to Players.LocalPlayer.PlayerScript after a player joins the server

I need to be able to copy a local script to all players and run it after the player joins the server. The script can be copied over at any time (from a few seconds to minutes or hours later). The current setup that I have will copy the script right away when the server spins up using StarterPlayerScripts and it works. But it does not work after the fact. After the server script executes, I can see the local script in StarterPlayerScripts but not PlayerScripts. If I manually copy the script to from StarterPlayerScripts to PlayerScripts in Explorer, the script will then execute.

So basically, I need to copy a local script from the server to the client using StarterPlayerScripts and then somehow copy that script into PlayerScripts so it will execute. Any ideas?

This is my current code on the server script:

This code is at the start of the server script.

local starterPlayer = game:GetService("StarterPlayer")
local localName = "SomeLocalScript"
local startScripts = starterPlayer.StarterPlayerScripts

This code is inside an initialization function within a module script in ServerScriptService that is called when the particular model is added to the workspace and it’s script executes. The model script requires the module script and calls the initialize function.

	-- **** Local Script
	-- Clones the local script so players will see local
	-- effects.  If the script does not exist, no errors
	-- will be thrown.
	if localScript == nil then
		localScript = startScripts:FindFirstChild(localName)
		if localScript == nil then
			local ls = script:FindFirstChild(localName)
			if ls ~= nil then
				localScript = ls:Clone()
				localScript.Enabled = true
				localScript.Parent = startScripts
			end
		end
	end
	
	-- **** Object List
	-- Creates an object value so the local script knows
	-- what to access on the client.
	if localScript ~= nil then
		local object = Instance.new("ObjectValue")
		object.Value = model
		object.Name = ident
		object.Parent = localScript
	end

Ident is the identity of the model, which is an attribute of the model.

It’s interesting to note that if a player joins after the above code is ran and the local script is inside StarterPlayerScripts, then it works normally.

2 things to note here:

  • You are supposed to parent the LocalScript to PlayerScripts, not StarterPlayerScripts (StarterPlayerScripts is used to automatically place LocalScripts in PlayerScripts once a player joins the server, parenting anything afterwards may cause some problems).

  • The server cannot access PlayerScripts, so you will only be able to use a LocalScript to parent another LocalScript to PlayerScripts.

In this case, you may need to use a RemoteEvent to fire from Server to Client so the client can parent the LocalScript you intend to use in PlayerScripts, as only the Client can access PlayerScripts (‘PlayerScripts’ will return nil if you attempt to call it from the server).

But why not just place that LocalScript (along with its associated children) under StarterPlayerScripts manually before testing?

I have. And it does work as intended when the player joins the server. Remember, these server scripts normally run when the server first spins up. That part works. It’s when I need to add a component to the workspace after the fact where I’m having issues. I can do the remote event quite easily though.

I’m beginning to think this might be a bug. I used the remote event like you suggested, and it does not work. After I parent the local script to StarterPlayerScripts, it can’t find it on the client. Even if I do WaitForChild for 10 seconds to give it time to replicate, yet it appears in Explorer immediately.

image

The event fires, and it prints the correct name of ‘JumpLocal’, and it shows up in Explorer. Yet, whenI do a StarterPlayerScripts:GetChildren() it’s not on the list.

Go figure.

There is something else I can try. Place the script in replicated storage and have the local script copy it from there. But given this issue, I’m not sure that will work either. Time for more testing.

You have to parent it to the player objects playerscript object.

I did that. It still does not show up on the list for GetChildren() even though it does show up in Explorer. It’s working through ReplicatedStorage so I’m going to run with that.

No you haven’t, but whatever. There’s no problem doing it the other way.

I’m not entirely sure what you are talking about then. Here’s what I did in Explorer: I manually copied the LocalScript from StarterPlayerScripts to PlayerScripts and the script was executing.

However, the script does not show up in StarterPlayerScripts from the perspective of a different LocalScript if the player is already logged into the server when the Server to Client replication happens, which in this case is after the player has been logged in for awhile. Since the copied script is not found, it’s not placed under PlayerScripts. That was the problem that I was having.

Since the server does not have access to PlayerScripts, and copying the LocalScript to StarterPlayerScripts doesn’t work, I used ReplicatedStorage to perform the copy and it works perfectly.