I want to say two things before you say anything:
#1: I am NOT using local scripts
#2: I am using remoteEvents to communicate between scripts.
For example, I have a string value 'slot' that only one player can have. I also have a regular script that clears the slot once a certain remoteEvent is triggered. Other normal scripts will fire that remoteEvent if certain things have been fulfilled, such as no health on humanoid, or a specific button has been pressed. Also, upon testing the game, I opened the dev console and it says 'FireServer can only be called from client'. I tried changing the script inside the button to FireServer into a local script but still no results.
local repStorage = game:GetService("ReplicatedStorage")
local exitQueue = repStorage:WaitForChild("exitQueue")
local gui = script.Parent
gui.MouseButton1Click:Connect(function()
exitQueue:FireServer()
end)
If a player presses on the GUI button the remoteEvent will be triggered. Note that the GUI is a SurfaceGui, like on the surface of a brick.
local repStorage = game:GetService("ReplicatedStorage")
local exitQueue = repStorage:WaitForChild("exitQueue")
exitQueue.OnServerEvent:Connect(function()
--do something
end)
And the code above is the receiving code. It does not work when on a server but works on the client, in studio.

2 comments
We need some code m8
It's not a matter of, don't use local scripts, but how the code is set up. Clients are only able to access some features so you use RemoteEvents to communicate to the server to do very important things. Provide code if you want further help.