Originally I was keeping my remotes within RepStorage, but that caused infinite yielding problems with my loading script, as it had to wait for them to load. So I moved them to repfirst, but now the game doesn’t work at all cause the server can’t access RepFirst. How can I work around this?
You don’t.
ReplicatedFirst and ReplicatedStorage have different purposes. ReplicatedStorage, as the name implies, is a container whose contents are replicated to both the server and client. ReplicatedFirst’s contents are replicated first to the client before anything else. Ideal for loading screens. So this should worsen the problem, not solve it. Your issue lies elsewhere.
My issue lies with remotes taking forever to load. When stored in repstorage, and I have a loading script, I have to fire certain remotes. If I remove the waitforchild and just delete any reference to remotes from my loading script the game loads almost instantly, however it doesn’t work then as I need to use remotes to tell the server to load the player.
If you ever find yourself needing to use a remote from ReplicatedFirst, you’ve hit a design smell. There should never be a case where you need a remote before the game has loaded and if you do, then your game structure is fundementally poor and needs to be redone to remove this dependency.
That’s the end of the story actually. Never use remotes immediately. You can still use remotes from ReplicatedFirst LocalScripts, sure, but don’t expect to be using them before Loaded fires. The server will not have replicated anything by then, so you’re out of luck.
Anaminus has a handy chart about how replication works. Although it’s purely observational, it’s the closest looking to actual behaviour if you perform your own crude tests as well. I’ve pretty much taken this as fact because of how accurate it seems.
Notice that ReplicatedFirst is handled first, then the DataModel is. ReplicatedStorage is part of the DataModel and thus your remotes. The answer to your question is you don’t, you can’t and you shouldn’t. If you find yourself in this predicament, then you need - not an option - to rethink your codebase’s structuring.
I use game.Loaded:Wait() before I rely on any remotes tho, so to me that should mean that I shouldn’t get infinite yields, but I do