Remote Functions and Events
Remote Functions and Events
/articles/Roblox Client Server Model|Roblox Client-Server Model
article before proceeding.
Some actions can only be performed by a server and other actions only by a client. For example, a player (client) may activate a GUI button, upon which the server needs to enact a game-wide change. In these cases, a RemoteEvent
or RemoteFunction
lets server-side Script|Scripts
and client-side LocalScript|LocalScripts
communicate with each other.
Difference Between Remote Events and Functions
While remote events and remote functions both allow communication between servers and clients, there are some notable differences:
Remote Event | |
---|---|
A RemoteEvent is designed for one-way communication. Using remote events, you can send information in the following ways: |
|
Client → Server |
Example — A player (client) presses the P key to drink an invisibility potion, then a RemoteEvent tells the server to make that player invisible to all other players. |
Server → Client |
Example — When a player's friend joins the game, that player (client) receives an on-screen notification. |
Server → All Clients |
Example — Before a race begins, a countdown timer is shown to all players. |
Client → Client(s) |
Example — A player chooses a new name for their in-game pet and shares it with friends. |
Remote Function | |
---|---|
A RemoteFunction is designed for two-way communication, such that it can send information across the server-client boundary and then wait for a response from the other side. |
|
Client → Server → Client |
Example — A player (client) fires a projectile, the server checks if a target was hit, and a response is sent back to the client with target-specific data (name of target, points to be awarded, etc.). |
Server → Client → Server |
(typically discouraged as noted below) |
Using Remote Events
To implement remote events, you must create a RemoteEvent
instance where both clients and the server can access it, for instance ReplicatedStorage
.
- In the Explorer window, click the
button next to ReplicatedStorage and insert a RemoteEvent instance.

- To use the new
RemoteEvent
instance with the following examples, rename it RemoteEventTest.

Client to Server
Game changes that happen within a LocalScript
only affect the local player. If a client needs to make a change that affects the entire server, the client can send a remote request to the server. For example, the following uses a remote event to create a new part which everyone on the server can see:
- Confirm that the
RemoteEvent
instance withinReplicatedStorage
is named RemoteEventTest. - Create a
LocalScript
withinStarterPlayerScripts
. In its code, point to theRemoteEvent
instance and fire an event with theRemoteEvent/FireServer|FireServer()
method:
RemoteEvent/FireServer|FireServer()
. This data will be available as additional parameters to the connected function:- Create a
Script
withinServerScriptService
. In its code, point to theRemoteEvent
instance and connect a function with anRemoteEvent/OnServerEvent|OnServerEvent
connection:
Player
who fired the event as its first parameter (player
), along with any additional parameters passed from the RemoteEvent/FireServer|FireServer()
call.
Server to Client
When something happens on the server side, it may be useful to notify a specific player with a remote event. To accomplish this:
- Confirm that the
RemoteEvent
instance withinReplicatedStorage
is named RemoteEventTest. - Create a
Script
withinServerScriptService
. In its code, point to theRemoteEvent
instance and fire an event with theRemoteEvent/FireClient|FireClient()
method:
Player
object must be passed along with the RemoteEvent/FireClient|FireClient()
call to indicate which specific player should be targeted.
RemoteEvent/FireClient|FireClient()
. This data will be available as additional parameters to the connected function:- Create a
LocalScript
withinStarterPlayerScripts
. In its code, point to theRemoteEvent
instance and connect a function with anRemoteEvent/OnClientEvent|OnClientEvent
connection:
Player
object with RemoteEvent/FireClient|FireClient()
. However, the receiving client-side function does not need to account for the player object in its list of parameters, so that function can begin with the second piece of data passed, in this case maxPlayers
.
Server to All Clients
Sometimes the game server needs to manage a routine and dispatch an event to all clients, for instance showing a countdown timer for all players. To do this:
- Confirm that the
RemoteEvent
instance withinReplicatedStorage
is named RemoteEventTest. - Create a
Script
withinServerScriptService
. In its code, point to theRemoteEvent
instance and fire an event with theRemoteEvent/FireAllClients|FireAllClients()
method:
RemoteEvent/FireClient|FireClient()
, the RemoteEvent/FireAllClients|FireAllClients()
method does not require a Player
object, as it fires the remote event to all connected players.
- Create a
LocalScript
withinStarterPlayerScripts
. In its code, point to theRemoteEvent
instance and connect a function with anRemoteEvent/OnClientEvent|OnClientEvent
connection:
Client to Client
Because of the articles/Roblox Client Server Model|client-server model
, communication between two or more clients must pass through the server. This is typically done as follows:
- The sending client calls
RemoteEvent/FireServer|FireServer()
. - On the server, the function connected to
RemoteEvent/OnServerEvent|OnServerEvent
hears this firing and callsRemoteEvent/FireClient|FireClient()
orRemoteEvent/FireAllClients|FireAllClients()
for the intended receiving client(s).
Using Remote Functions
As stated earlier, remote functions are designed to send a request across the server-client boundary and then wait for a response from the other side.
Before you can implement a remote function, you must create a RemoteFunction
instance where both clients and the server can access it, for instance ReplicatedStorage
:
- In the Explorer window, click the
button next to ReplicatedStorage and insert a RemoteFunction instance.

- To use the new
RemoteFunction
instance with the following examples, rename it RemoteFunctionTest.

Client to Server
A client-side RemoteFunction
is “invoked” when that client wants the server to do something and be notified when the server is done. For example, the following approach sends a request from the client, creates a part on the server, and returns it back to the client.
- Confirm that the
RemoteFunction
object withinReplicatedStorage
is named RemoteFunctionTest. - Create a
Script
withinServerScriptService
. In its code, point to theRemoteFunction
instance and bind a function to itsRemoteFunction/OnServerInvoke|OnServerInvoke
callback using the=
operator:
Player
who invoked it as the first parameter (player
).
RemoteFunction/OnServerInvoke|OnServerInvoke
at a time. If you assign multiple functions, only the last one assigned will be used.
- Create a
LocalScript
withinStarterPlayerScripts
. In its code, point to theRemoteFunction
instance and invoke the server with theRemoteFunction/InvokeServer|InvokeServer()
method:
LocalScript
that invokes it will not resume execution.
RemoteFunction/InvokeServer|InvokeServer()
call and it will be available as additional parameters to the connected function:Server to Client
RemoteFunction/InvokeClient|InvokeClient()
as it can be potentially game breaking. For client-only actions that don't require a callback, like updating a GUI, a server-to-client remote event should be used instead. If RemoteFunction/InvokeClient|InvokeClient()
is used, risks include:
- If the client throws an error, the server will throw the error too.
- If the client disconnects while it's being invoked, the
RemoteFunction/InvokeClient|InvokeClient()
call will error. - If the client never returns a value, the server will hang forever.
Parameter Limitations
Any type of Roblox object such as an Enumeration, Instance
, or userdata can be passed as a parameter when a RemoteEvent
is fired or a RemoteFunction
invoked. Lua types such as numbers, strings, and booleans can also be passed, although there are some limitations on how data can be passed.
Mixed Tables
Avoid passing a mixed table (some values indexed by number and others by key), as only the data indexed by number will be passed. For example, when the server receives the colorData
table illustrated below, it will only see indices 1 and 2 containing "Blue"
and "Yellow"
while the other data will be lost in the transfer. Note, however, that sub-tables do not need to be indexed in the same way as their parent — in other words, as long as each individual sub-table is indexed with the same type, all of the data will be preserved.
Non-String Indices
If any indices of a passed table are non-string type (Instance
, userdata, function, another table, etc.), those indices will be converted to a string.
Metatables
If a table has a articles/Metatables|metatable
, all of the metatable information will be lost in the transfer. For example, when the server receives the following table, the truck
table that was passed will have the Name
property but not the NumWheels
property that was part of the Car
metatable.
Non-Replicated Instances
If the value being sent is only visible to the sender, nil
will be passed instead of the value. For example, if a server tries to pass a descendant of ServerStorage
, the client listening to the event will see a nil
value because that object isn’t replicated to the client.
Similarly, if a client creates a part and tries to pass it to the server, the server will see a nil
value because the part isn’t replicated to the server.