Return of Changes to Non-ReplicatedFirst Loading Order

This topic was automatically opened after 16 minutes.

To those looking to find the DevHub articles on ReplicatedFirst and WaitForChild, I’ve linked them below for your convenience. (So that you don’t have to search on the Developer Hub yourself!)

ReplicatedFirst
WaitForChild

Anyways, love these changes!

8 Likes

It’s nice to have a reminder beyond just editing the other post. But, the new date of it being enabled in Studio (Jan 19) is within the “old information” section with the same wording, which I almost missed reading. It’d be great if that was moved to the end.

Also, the “copied” part of that previous topic here is a bit jumbled up in the actual new information (i.e. the introduction and the “questions asked previously”). To account for quick and easy readability, can you store all the info in a collapsible menu like “previous post” or something? That way devs don’t miss any new info thinking the rest is just the old stuff.

Edit: It has been done, thank you!

5 Likes

Thanks for the links, they must’ve gotten lost in the copy paste process. I’ve added them to the post!

4 Likes

I believe the code should be formatted here.


This update is great! Thanks to the engineers who rolled this out!

2 Likes

Seems like a great change to me!

Just one question, if a certain script is negatively affected by this change, what kind of a warning should we expect in the output section to receive? I’m not familiar with ReplicatedFirst, however, if I do start to use it prior to January 19th, I would like to know.

The most likely error you would see is the same error you would see if you used . to access something that doesn’t exist on the client (yet):

  15:29:57.399  > print(workspace.NotAChild)  -  Studio
  15:29:57.400  NotAChild is not a valid member of Workspace "Workspace"  -  Edit
  15:29:57.400  Stack Begin  -  Studio
  15:29:57.400  Script 'print(workspace.NotAChild)', Line 1  -  Studio
  15:29:57.400  Stack End  -  Studio
5 Likes

noice looking good :slight_smile: this solved many problems lol

What are the exact benefits of this? Will this change introduce faster loading in general, or maybe less thread hanging from WaitForChild?

(This is simply based on my understanding of everything)

This change first rolled out for improved game joining process, or in other words (as you said) faster loading in general.

However, as said above in the quote from this article, there were multiple issues when changes rolled out the first time.

The link above leads to the point in the thread for the changes made (back in August) where users started reporting issues. There were several UI errors and multiple ping spikes when players joined certain games. Eventually, they did disable the changes so that they could fix the errors, as already stated.

Now that these changes are back and improved, it should help with a faster game loading process and not cause errors in the clients.

I do have just one last question.

Could it be possible to implement this in a way where it would be optional to turn this on or off (for now)? Therefore, if there did happen to be any errors we could report it, and then turn it off so that our games wouldn’t be affected.

This is part of a group of changes we are making targeting all aspects of the join. Most of the other changes are fully internal/transparent to game developers, but we couldn’t find a way to do that for this particular change.

In our internal testing, we saw ~4x improvement in join snapshot processing for our core test game (this number will vary for different games, but should be a significant improvement in all cases)
Before:
o1join_off
After:
o1join_on

Additionally, this resolves some other downstream server performance impacts of joins. Here we have the summary view from the microprofiler. We perfomed periodic groups of 5 joins. Before the change you can see clear performance spikes/lag in the frames where we process joins, after those spikes are almost entirely gone

Before:


After:

We also anticipate some benefits in total bytes needed to join games, which should have a direct (positive) impact on join times, but in our tests that improvement varied between games so I don’t want to quote a specific improvement number.

Not all of the gains will be realized from this individual change, but there will be some improvement, and this change is necessary for continuing on this path.

9 Likes

It would be nice to have a method argument that allows us to reliably obtain the descendants of the instance we are waiting on (similar to how the old system worked). WaitForChild is a pretty long thing to type for every child object and sometimes it’s impossible to know just how many child objects there should be.

object:WaitForDescendantsLoaded() may be a good option or object:WaitForChild(“abcd”, true) (true being the argument telling the method to use the old way of handling this) would be great for improving the quality of life for developers.

Edit: I like this update because it more clearly achieves what you’d expect using WaitForChild, but I don’t see any good patches and alternatives for devs who still rely on the old system and don’t have the patience to call wait for child over and over and over again.

2 Likes

Yeah- I get what you mean. I’ve been having that problem too.

So for clarification, would it be ideal for me to put the example code block at the top of the load script I have in ReplicatedFirst for my custom load screen to make sure all the UI elements the script is indexing from a different GUI all exist? (I use :GetDescendants() to preload them all.)

1 Like

You should make sure that there’s some guarantee in place that all of the Instances your load screen script is working with exists before you use them. Generally I think this is done by calling WaitForChild. Calling GetDescendants may not be safe in this use case if the script doesn’t do anything to guarantee that the descendants it’s getting have been replicated by the time GetDescendants is called. Please remember that GetDescendants does not automatically call WaitForChild

That seems like an impossibility though. The UI I have has hundreds of UI elements, am I really going to have to write individual declarations for each one? :grimacing:

I think they misunderstood your question (a lot of Roblox engineers are not as familiar with Roblox from a developer POV).

It is totally valid to check if #something:GetDescendants() exceeds a certain amount to check how many things have been replicated under something.

5 Likes

Yes, that should also work. Sorry C_Sharper, didn’t know this was what you meant, and thanks buildthomas for the answer!

4 Likes

Hi Developers,

We have activated the feature for Studio and are planning to activate the feature across all games on production on February 2.

Please let us know if you guys have any concerns or think you need more time to make sure your games’ scripts properly wait for instances to arrive during Game Join.

2 Likes