User avatar
Site Admin
Roblox RemoteEvents: Client-Server Communication Explained
Roblox RemoteEvents: Client-Server Communication Explained

RemoteEvents are the backbone of multiplayer communication in Roblox. They let you send messages between the client and the server without yielding for a response. If you are new to Roblox scripting, this is the first system you need to understand.

The Client-Server Model

In Roblox, the server is the container for all clients. Each client represents a player in the game. A LocalScript runs on the client and can only affect what that player sees. A Script runs on the server and can affect the entire game state.

A LocalScript cannot change what other players see. A Script cannot touch one player's screen. RemoteEvents bridge this gap.

Setting Up a RemoteEvent

In Roblox Studio, navigate to ReplicatedStorage. Create a RemoteEvent and name it something descriptive, like

Code: Select all

ButtonPressed
or

Code: Select all

AwardPoints
. The RemoteEvent must be in ReplicatedStorage because both the server and the clients need to see it. ServerStorage and ServerScriptService are server-only, so a LocalScript waiting for a remote there waits forever.

Client to Server Communication

A LocalScript calls

Code: Select all

FireServer()
on the RemoteEvent. The server hears it on

Code: Select all

OnServerEvent
. The first parameter of the server handler is always the Player object of the client that fired the event. Additional parameters follow.

Here is a simple example. The client sends a request to delete a part:

LocalScript:

Code: Select all

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("DeletePart")
local part = workspace:FindFirstChild("PotentiallyAffectedByRequest")

UIS.InputBegan:Connect(function(input, gameProcessedEvent)
    if input.KeyCode == Enum.KeyCode.Delete and not gameProcessedEvent then
        RemoteEvent:FireServer(part)
    end
end)
Script (server):

Code: Select all

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("DeletePart")

RemoteEvent.OnServerEvent:Connect(function(player, part)
    part:Destroy()
end)
Server to Client Communication

The server calls

Code: Select all

FireClient(player, ...)
to send a message to one player. The first argument is the Player object. The client hears it on

Code: Select all

OnClientEvent
. The client handler does not receive the Player object because the client can get it with

Code: Select all

Players.LocalPlayer
.

To send a message to all players, use

Code: Select all

FireAllClients(...)
. It takes no Player argument.

RemoteEvents vs RemoteFunctions

RemoteEvents are fire-and-forget. The sender carries on immediately. RemoteFunctions are request-response. The caller yields until the other side returns a value.

Use a RemoteEvent when you do not need a reply. Use a RemoteFunction when the client cannot carry on without the answer, such as checking whether a code is valid.

Avoid

Code: Select all

InvokeClient
(server calling a client function). A client that errors, leaves, or never returns breaks the server's call. If the server needs information from a client, fire a RemoteEvent, have the client reply on another RemoteEvent, and treat a missing reply as a normal case.

Security: Never Trust the Client

An exploiter can fire any RemoteEvent or invoke any RemoteFunction, as often as they like, with any arguments. The one thing they cannot fake is the first parameter: Roblox fills in the Player who sent it. Everything after that must be checked before the server acts on it.

On the server, validate the type, range, and ownership of every argument. Check the player's distance. Rate-limit how often they fire. Never send a price, a reward, or a damage amount from the client. Keep the real data on the server and treat the client's arguments as a request to check.

Message Reliability

RemoteEvents are reliable and ordered. If a message is lost in transit, Roblox retransmits it until it arrives, as long as the recipient stays connected. Messages arrive in the order you fire them, even across different RemoteEvent instances.

If no handler is connected when a message arrives, Roblox queues it and delivers it once a handler connects. The queue is limited in both count and memory. Once it is full, Roblox discards further messages and logs an error.

Sources
[1] Remote events and callbacks - Roblox Creator Hub
[2] Remote Events In A Nutshell - Roblox DevForum
[3] Roblox RemoteEvent Tutorial - Rocode