Once upon a time there was a problem: How do I send a client an object from a location that’s only visible to the server (e.g. from the ServerStorage)?
We could serialize an object and sending it through RemoteEvents, but that’s just messy, and it’s impossible to serialize unions anyway. We could parent it to a non-server location, say player.TakeMe (custom folder created for this purpose) and then fire a remote event telling the client what to do with that object, but that’s messy as well and that object replicates to every player in the game which wastes bandwidth and potentially shows other clients something they’re not supposed to see. We were all out of ideas and then somebody decided “Hey, let’s parent it to the PlayerGui!” The contents of the PlayerGui are not replicated, but the server can still see the PlayerGui itself. Other clients can’t see another client’s PlayerGui object, but the server can. If we parent an object to the PlayerGui it is directly given to the client, it’s not replicated to other players, localscripts run when parented there which is useful if we want to run clientside code (e.g. mute a client) without having to get their permission from a RemoteEvent/Function, and there’s no behind-the-scenes mess that we have to worry about (i.e. parenting it to one place and then telling the client that the object is there).
That is all wonderful, but there is one downside to the PlayerGui. It resets when the player respawns. ROBLOX acknowledged that this was an issue and created PlayerScripts, but unfortunately PlayerScripts are not visible to the server. In order to locate something there we’d have to put an ugly line of code at the top of every script we wanted to put there from the server that moved it from the PlayerGui to PlayerScripts. It’d be nice if the PlayerScripts object itself was visible to the server (but not the contents).