RemoteFunction
A server should rarely invoke a client via 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 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 InvokeClient() call will error.
- If the client never returns a value, the server will hang forever.
A RemoteFunction is used to create in-game APIs that both the client and the server can use to communicate with each other. Like BindableFunction, a RemoteFunction can be invoked (called) to do a certain action and return the results.
If the result is not needed, we recommend that you use a RemoteEvent instead, since its call is asynchronous and doesn't need to wait for a response to continue execution. See Remote Functions and Events.
Code Samples
-- In a server script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage.RemoteFunction
function remoteFunction.OnServerInvoke(player, name)
print("Hi, my name is", name, "and this invocation came from", player.Name)
return player.Name
end
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPopupRequest = Instance.new("RemoteFunction")
createPopupRequest.Name = "CreatePopupRequest"
createPopupRequest.Parent = ReplicatedStorage
Players.CharacterAutoLoads = false
local function onPlayerAdded(player)
createPopupRequest:InvokeClient(player)
player:LoadCharacter()
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local createPopupRequest = ReplicatedStorage:WaitForChild("CreatePopupRequest")
local function onCreatePopupRequested()
local screen = Instance.new("ScreenGui")
screen.Parent = playerGui
local closeButton = Instance.new("TextButton")
closeButton.Text = "Welcome to the game! Click me to play!"
closeButton.Size = UDim2.new(0, 300, 0, 50)
closeButton.Parent = screen
closeButton.MouseButton1Click:Wait()
closeButton.Visible = false
end
createPopupRequest.OnClientInvoke = onCreatePopupRequested
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPartRequest = Instance.new("RemoteFunction")
createPartRequest.Parent = ReplicatedStorage
createPartRequest.Name = "CreatePartRequest"
local function onCreatePartRequested(player)
print(player.Name, "wants to create a new part")
local newPart = Instance.new("Part")
newPart.Parent = workspace
return newPart
end
createPartRequest.OnServerInvoke = onCreatePartRequested
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPartRequest = ReplicatedStorage:WaitForChild("CreatePartRequest")
local newPart = createPartRequest:InvokeServer()
print("The server created this part for me:", newPart)
Summary
Properties
Methods
Calls the function bound to the RemoteFunction by RemoteFunction.OnClientInvoke for the given Player. Use only in a Script.
Calls the function bound to the RemoteFunction by RemoteFunction.OnServerInvoke and returns what that function returns. Use only in a LocalScript.
Events
Callbacks
Properties
Methods
InvokeClient
Calls the function bound to the RemoteFunction by RemoteFunction.OnClientInvoke for the given Player. Use only in a Script.
In practice, the server does not often invoke the client, as clients typically do not have information that the server doesn't have, and actions that only a client can take, such as displaying a GUI, typically do not require a callback. As such, RemoteEvent:FireClient() is recommended as an asynchronous method that doesn't need to wait for a response to continue execution.
See also RemoteFunction:InvokeServer() and RemoteFunction.OnServerInvoke for invoking the server from a client.
Warning
If a client throws an error or disconnects while it is being invoked from the server, RemoteFunction:InvokeClient() will error. It is therefore recommended to wrap this method in pcall() so it doesn't stop execution of other code.
For more information, see Remote Events and Functions.
Returns
Values returned by RemoteFunction.OnClientInvoke.
Code Samples
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPopupRequest = Instance.new("RemoteFunction")
createPopupRequest.Name = "CreatePopupRequest"
createPopupRequest.Parent = ReplicatedStorage
Players.CharacterAutoLoads = false
local function onPlayerAdded(player)
createPopupRequest:InvokeClient(player)
player:LoadCharacter()
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local createPopupRequest = ReplicatedStorage:WaitForChild("CreatePopupRequest")
local function onCreatePopupRequested()
local screen = Instance.new("ScreenGui")
screen.Parent = playerGui
local closeButton = Instance.new("TextButton")
closeButton.Text = "Welcome to the game! Click me to play!"
closeButton.Size = UDim2.new(0, 300, 0, 50)
closeButton.Parent = screen
closeButton.MouseButton1Click:Wait()
closeButton.Visible = false
end
createPopupRequest.OnClientInvoke = onCreatePopupRequested
InvokeServer
A client invoking the server is necessary when the server either has access to information the client does not, or the client requests an action that only the server can perform. Used in a LocalScript, RemoteFunction:InvokeServer() calls the function bound to the RemoteFunction by RemoteFunction.OnServerInvoke and returns what that function returns.
If a returned result is not needed, it's recommended to use RemoteEvent:FireServer() instead, as its call is asynchronous and doesn't need to wait for a response to continue execution.
See also RemoteFunction:InvokeClient() and RemoteFunction.OnClientInvoke for invoking a particular client from the server.
For more information, see Remote Events and Functions.
Returns
Values returned by RemoteFunction.OnServerInvoke.
Code Samples
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPartRequest = Instance.new("RemoteFunction")
createPartRequest.Parent = ReplicatedStorage
createPartRequest.Name = "CreatePartRequest"
local function onCreatePartRequested(player)
print(player.Name, "wants to create a new part")
local newPart = Instance.new("Part")
newPart.Parent = workspace
return newPart
end
createPartRequest.OnServerInvoke = onCreatePartRequested
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPartRequest = ReplicatedStorage:WaitForChild("CreatePartRequest")
local newPart = createPartRequest:InvokeServer()
print("The server created this part for me:", newPart)
Events
Callbacks
OnClientInvoke
Returns
Code Samples
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPopupRequest = Instance.new("RemoteFunction")
createPopupRequest.Name = "CreatePopupRequest"
createPopupRequest.Parent = ReplicatedStorage
Players.CharacterAutoLoads = false
local function onPlayerAdded(player)
createPopupRequest:InvokeClient(player)
player:LoadCharacter()
end
Players.PlayerAdded:Connect(onPlayerAdded)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local createPopupRequest = ReplicatedStorage:WaitForChild("CreatePopupRequest")
local function onCreatePopupRequested()
local screen = Instance.new("ScreenGui")
screen.Parent = playerGui
local closeButton = Instance.new("TextButton")
closeButton.Text = "Welcome to the game! Click me to play!"
closeButton.Size = UDim2.new(0, 300, 0, 50)
closeButton.Parent = screen
closeButton.MouseButton1Click:Wait()
closeButton.Visible = false
end
createPopupRequest.OnClientInvoke = onCreatePopupRequested
OnServerInvoke
Returns
Code Samples
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPartRequest = Instance.new("RemoteFunction")
createPartRequest.Parent = ReplicatedStorage
createPartRequest.Name = "CreatePartRequest"
local function onCreatePartRequested(player)
print(player.Name, "wants to create a new part")
local newPart = Instance.new("Part")
newPart.Parent = workspace
return newPart
end
createPartRequest.OnServerInvoke = onCreatePartRequested
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local createPartRequest = ReplicatedStorage:WaitForChild("CreatePartRequest")
local newPart = createPartRequest:InvokeServer()
print("The server created this part for me:", newPart)