I wanted to share some information about some unclear points regarding the starting of localscripts and when replication occurs. I will also share the guarantees that we will provide soon.
Until now, developers need to guess when localscripts starts running and what instances can be referenced at start. Today, I wanted to explain a little about some guarantees that will go live soon that will help you with what is needed and what’s not needed when writing code in your localscripts.
To reiterate, localscripts runs on client-only and will only run if they are descendants of the following places
- The Localplayer’s Backpack
- The Localplayer’s Character model
- The Localplayer’s Gui
- The Localplayer’s PlayerScripts
- Inside the ReplicatedFirst service
From the list above, we can separate the location of a localscript into 2 categories:
- LocalScripts within ReplicatedFirst service
- Other LocalScripts that are in the backpack, playergui, the character model, and playerscripts
These scripts are good when you want to make a custom loading screens, as these localscripts will be the first ones executing; they are extremely handy when running preparation on the clients during the client is loading the game.
The timing of these localscripts in ReplicatedFirst works like the following:
- When client first connects to the game, ReplicatedFirst service is replicated. Within this service, it will contain LocalScripts that you intended to run first.
- After ReplicatedFirst service is completely replicated to the run, the localscripts within this service will start running.
- It is important to note that these scripts will be running on the client while the rest of the game is being loaded. This means, at the starting point of these scripts, you can only rely on game.ReplicatedFirst to be completely done replicating. Other services (also including game.Workspace) will most likely be incompletely replicated at this point.
Therefore, if you want to reference any instance that you have already created (for example, if you had created these parts in Studio), you will need to wait for game:isLoaded() to return true. For example:
while not game:IsLoaded() do wait() end
However, if you want to reference the instance as soon as it is replicated, you may use WaitForChild() to wait for the replication of this instance in your ReplicatedFirst localscripts.
Please keep in mind about the following about WaitForChild():
- If a timeout is not specified in the WaitForChild() call, 5 seconds after the call; a warning message will be printed stating that WaitForChild() may not return.
- If a timeout is specified in the WaitForChlid() call, this call may return nil after the timeout time has elapsed.
- If the WaitForChild() call returns a non-nil value, it is safe to access that part/instance only. Descendants are not guaranteed to exist under this condition.
Which one should you use in your ReplicatedFirst scripts? (Loop until game:IsLoaded() == true or WaitForChild() )
- If you would like to have access to all pre-made parts in Studio and don’t mind waiting until the game is completely loaded, waiting for game:IsLoaded() == true is simpler, but might take longer.
- If you need access the part as soon as it arrives but don’t mind having to repeatedly call WaitForChild(), WaitForChild() will give you a quicker response.
After ReplicatedFirst service is completely replicated and the scripts in ReplicatedFirst service are running, the rest of your game is loaded on the client. During this time, other services and the workspace are replicated to the client.
Other localscripts - Player’s Backpack, Character Model, PlayerGui, and PlayerScripts
Next are the scripts that are in the player’s backpack, character model, playergui, and playerscripts.
These localscripts have a different start time than the ones in ReplicatedFirst. These scripts will start after the client has completely loaded the rest of the game.
The timing of these localscripts works like the following:
- After ReplicatedFirst is completely replicated, the rest of the game ( not including the player’s backpack, gui, character model, or playerscripts) are replicated to the client.
- After client has received all of those, the client will populate the localscripts in the localplayer’s backpack, gui, character model, and playerscripts (if any)
- The localscripts from step 2 are started when they are received.
Therefore, if you had made a part in Studio (and had not modified/deleted this part when the player joins), you can reliability reference that part.
Localscripts and dynamically created instances
After game is in progress, localscripts can continue to run. However, caution should be taken when localscripts are accessing dynamically generated instances.
- If you want to access parts/instances that are dynamically created by a server script, WaitForChild() will be needed in the localscript before accessing. Since network replication is not instantaneous, we will need to ensure the part/instance has replicated to the client using WaitForChild(). After WaitForChild() returns a non-nil value, the instance can be accessed and its properties are valid and can be accessed.
- Again, after WaitForChild() returns a non-nil value, the instance is ready to be worked with and all its properties can be referenced.
If your localscript is dynamically cloned then parented to the local player’s backpack, player’s character model, or playergui, please use WaitForChild() before accessing the instance for the safest results as these localscripts will run as soon as it is replicated. However, on the server, if the part/instance is created and parented to the data model before cloning and parenting to the player’s backpack, character model, or playergui, it is ok to access the instance and its properties without WaitForChild() since replication is done in order.
What can you expect when writing any localscripts?
- ‘game.Players.LocalPlayer’ will always be non-nil
- ‘game.Players.LocalPlayer.PlayerGui’ will always be valid *Not yet live
What can you expect when writing localscripts within ReplicatedFirst?
- All instances within ReplicatedFirst are readily accessible.
- These localscripts will be running while the rest of the game is being loaded on the client.
- It is best not to reference instances outside of ReplicatedFirst; however, it can be done if you wait for ‘game:IsLoaded() == true’ or call
WaitForChild()before trying to reference that instance
What can you expect when writing localscripts within the Player’s backpack, character model, playerGui, and playerscripts?
- Any part you have pre-made in Studio will be readily accessible.
Here’s a visualization of it:
Please keep in mind that these guarantees are not yet active. We will keep this post updated to let you know when these go live!
Feel free to ask questions about this update, or provide feedback on any effects it might have on your game!