Starter Container Script Execution Guarantees

I’ve been experimenting to see the behaviour in how LocalScripts are cloned to the appropriate starter containers, or more specifically, at which point do LocalScripts execute?

My initial theories were:

  • LocalScripts execute when the entire container has finished cloning.
  • LocalScripts execute instantly upon said script getting cloned.

It turns out both of my theories are correct, however, it is dependent on the starter container used.

  • StarterGui - LocalScripts execute when the entire container has finished cloning.
  • StarterPack - LocalScripts execute instantly upon said script getting cloned.
  • StarterCharacterScripts - LocalScripts execute instantly upon said script getting cloned.
  • StarterPlayerScripts - LocalScripts execute when the entire container has finished cloning.

The Studio console script I used to set up the environment is as follows.

SOURCE = "local EXPECTED_COUNT = 2000 ActualCount = #script.Parent.Parent:GetDescendants() print(\"I see \" .. tostring(ActualCount) .. \". The expected count is \" .. tostring(EXPECTED_COUNT) .. \". Correct?: \" .. tostring(EXPECTED_COUNT == ActualCount))"

local SystemFolder = Instance.new("Folder", game.Selection:Get()[1]) -- Selection should be a starter container in this scenario.

for i=1,1000 do
	local folder = Instance.new("Folder")

	local localScript = Instance.new("LocalScript")
	localScript.Source = SOURCE
	localScript.Parent = folder

	folder.Parent = SystemFolder
end

I am wondering if the behaviours listed above are guaranteed, or are more of a “side-effect”/subject to change, and therefore shouldn’t be relied upon.

I don’t think you should be relying on any of this. To me all of it just boils down to race conditions and that is not good.

You can try using a framework like Aero to maintain use time for services because you’re guaranteed to know when they’re ready

Frameworks like Aero can certainly save time and give developers an easier life, although I’m wishing to gain a better understanding of engine behaviour.

Like you say, Aero is able to guarantee it (or to the extent I’ve personally never seen an issue with ModuleScripts not being present). Describing the client-side perspective (as this is where these uncertainties are), it seems Aero is just calling WaitForChild to await for the Modules folder (reference), unless I’m missing something.