I have been developing frameworks for quite a while, and a constant issue I run into is how to deal with ReplicatedFirst.
Problem
Let’s say I have a loading screen in ReplicatedFirst, and some module from a libs/packages folder in ReplicatedStorage like a signal library.
If the loading screen needs to use that module, then the most logical case would be to use WaitForChild(). However, as the docs say, this ruins the point of using ReplicatedFirst in the first place:
The solution then, would be to either move the loading screen elsewhere, or the module to ReplicatedFirst.
If we do the former, we would no longer have the initial replication that ReplicatedFirst gives, which could cause the player to see the game for a split second before the loading screen appears.
If we do the latter, we mess up the codebase’s organisation since one module is out of the libs folder.
To solve that, we could just move the entire libs folder to ReplicatedFirst to make up for it. But having more objects in ReplicatedFirst would theoretically slow down the service’s loading time, and the visual stutter could still happen.
We could also just duplicate the module and keep one in both ReplicatedFirst and the libs folder, but having two of the same module would be ocd triggering.
Caveats
This paradox is born from chasing perfection. In truth, most players would not care about a visual stutter and I could just live with the minor inconvenience of a less-organised framework, no biggie. But is there a way to truly solve this problem?
Or have the module as a package both in ReplicatedFirst and ReplicatedStorage. Otherwise, you could just either separate copy-paste the bare-bones functionality into a RF module, or just have the RS module use RF as a base. It really depends on what that module does for your loading screen?
Rather than duplicating my modules (which complicates maintenance)
or re-parenting my modules (which is ugly),
I would rethink what you’re trying to achieve with ReplicatedFirst.
Personally, my goal would be to prevent the player from seeing the skybox or any other 3D content load in when they join the game.
Do I need the entire loading screen for this? No.
All I need is a bare-bones black rectangle to block everything off, which I can leave instanced until the loading screen logic located in StarterPlayerScripts/ReplicatedStorage (whatever your structure looks like) kicks in to display its own graphics, eventually removing the rectangle.
With this, you won’t run into the dependency issue ever, because the loading screen logic is part of the regular setup.
In TL;DR: I think you’re trying to do too much in ReplicatedFirst when it’s not necessary, assuming your initial goal of using this service is to block the player from seeing things they shouldn’t.
There is no point in adding a timeout like 9999 seconds to WaitForChild if your goal is to indefinitely yield until the object is found. When unspecified, it’ll yield forever until the instance is found (outputting a warning after a certain number of seconds however)