I am tempted to misuse ReplicatedFirst as a static client-only code container

As far as I know, the intended way to store client-only code is either inside StarterPlayerScripts or StarterCharacterScripts. However, this has been rather painful for several reasons—especially when using a ModuleScript-only architecture:

  1. Autofill is broken because the modules are cloned and parented to LocalPlayer.PlayerScripts at runtime.
  2. Require paths are convoluted compared to those used in ServerScriptService.
  3. Modules need to be wrapped in an additional folder just to avoid getting mixed up with Roblox’s default modules.
  4. Clicking on errors or prints doesn’t open the module after stopping the game.
  5. There’s a duplicate of all the modules under StarterPlayerScripts.
  6. StarterPlayerScripts is buried under StarterPlayer, making access less convenient.

Since there is no ClientScriptService, I had to get creative.

I didn’t want to pollute ReplicatedStorage with client-only code, so I used ReplicatedFirst instead. I’m aware of its technical quirks, but as far as I know, none of them are truly deal-breakers:

  1. LocalScripts in ReplicatedFirst run before game.Loaded—which is fine, because I only use ModuleScripts and start them with a game.Loaded check just in case.
  2. I lose the built-in distinction between pre- and post-game.Loaded code—but I reintroduce this distinction with a ReplicatedFirst.Intro folder, which usually only contains a single module anyway.
  3. If I ever decide to add a custom loading screen, it might take slightly longer to appear, since it can only show up after all client code is loaded—but the delay is usually no more than 3 seconds.

Am I missing something here, or is this the new go-to?

2 Likes

I personally use StarterPlayer only to house a singular localscript that requires all of my modules placed under ReplicatedStorage. Maybe you can consider that.

1 Like

ReplicatedFirst is meant for loading screens and critical game setup as far as I know, not usually gameplay code.
I also use a module based architecture and I don’t have any issues with the StarterPlayerScripts/StarterCharacterScripts folders. I could also see how using ReplicatedFirst for client code can become an issue with PlayerGui stuff, as PlayerGui isn’t available when it runs. You could of course just wait, but I think this just adds unneeded complexity.
I just don’t recommend it

I understand the connotation. My idea is to just ignore it and only care about the technical properties of RF. If I didn’t do this I would do what @HeCatchThose described and put the client stuff in ReplicatedStorage.Client. I just think that is pretty ugly and am willing to misuse RF just for that nice and clear server/client/shared boundary that it provides.

This is how i set up my games, Client is a Script with RunContext set to client to be able to run in ReplicatedStorage

3 Likes

Yeah thats the right way to go about things.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.