A tutorial for server and client communication

The player is called a client, while everybody together is called the server.
The server is used for damaging players, NPC behavior, LoadCharacterAsync, and much more.
The client is used for GUI/UI, handing local movement, and if you’re a good developer, visual effects.

Please be aware that I’m a beginner scripter and this information may be slightly wrong.

Okay. First, the player clicks a GUI button. We want it to do something on everybody’s screen.
How are we going to do that?

Well we need a LocalScript inside of the ImageButton or TextButton.

script.Parent.MouseButton1Up:Connect(function()
	game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("RemoteEvent"):FireServer()
end)

Assuming you have a folder in ReplicatedStorage called Remotes, which I recommend to do since it organises everything. RemoteEvent is the RemoteEvent instance, but you should name it something else to make it cleaner, such as BuyItem.

script.Parent.MouseButton1Up:Connect(function()
	game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("BuyItem"):FireServer()
end)

Now how does the server give that player the item?
I’ll paste the script below, but please be aware you can’t just put it in your game straight away.
Without organizing everything and having basic scripting knowledge, this won’t do anything.

local item = game.ReplicatedStorage:WaitForChild("Items"):WaitForChild("ToolNameHere")

local v = 1

game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("BuyItem").OnServerEvent:Connect(function(player)
	if player and player:IsA("Player") and player:WaitForChild("leaderstats").Money.Value >= item:GetAttribute("Price") then
		print(player.Name.. "brought ".. item.Name)
		if v == 1 then
			item:Clone().Parent = player:FindFirstChildOfClass("Backpack") or player.Character
		else
			item:Clone().Parent = player.Character
		end
	else
		print(player.Name.. "didn't have enough money to buy".. item.Name)
	end
end)

Alright, now we know how to make the client tell the server information, but what about vice-versa?

FireServer() won’t work, it must be FireClient()?
Well yeah, but its more advanced than that.
How would FireClient() know which player? will it tell every client?
No, that would be FireAllClients()
FireClient(game.Players.PlayerName) would be correct.

game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("ServerToClient"):FireClient(game.Players:FindFirstChildOfClass("Player"))

or for everybody,

game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("ServerToClient"):FireAllClients()

Now how will the client know when the server tells it something?
Like this:

game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("ServerToClient").OnClientEvent:Connect(function()
	--omg the server told us something
	print("omg omg omg")
end)
1 Like

Hi, just wanted to help polish this off a bit. Firstly, i would use script.Parent.Activated instead of script.Parent.MouseButton1Up, as that makes it that if s mobile player clicks it, it still works, same with PC. Also, with the

game:GetService("ReplicatedStorage"):WaitForChild("Remotes"):WaitForChild("ServerToClient"):FireClient(game.Players:FindFirstChildOfClass("Player"))

this will send it to the first player in the players, which will work fine when it’s one player in studio or in game, but if there’s a lot, you may want to find a different way of determining which player to send to.