> For the complete documentation index, see [llms.txt](https://docs.overdare.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.overdare.com/development/api-reference/classes/remotefunction.md).

# RemoteFunction

RemoteFunction : `Instance`

## Overview

A RemoteFunction is an Object used to handle requests and responses between the client and server, supporting synchronous, two-way communication.

Since it needs to be accessible from both the server and the client, it should be placed in a shared location such as ReplicatedStorage or Workspace.

The script that makes the call yields until the target callback returns, and it can receive multiple return values at once.

Arguments sent by the client are passed to the function assigned to OnServerInvoke as-is, without any validation by the engine. You have to validate their types and value ranges on the server yourself.

Direct communication between different clients is not supported. To pass a value from one client to another, it has to go through the server.

If you don't need a return value, RemoteEvent is a better fit.

## Properties

### OnClientInvoke

`Value`

Specifies the function to run on the target client when the server calls the InvokeClient method. Set it from a LocalScript on the client.

Because it is not an event, you set it by assignment rather than with Connect(), and only one function can be assigned. For details on its behavior and caveats, see OnClientInvoke in the Callback section.

#### Code Samples

### OnServerInvoke

`Value`

Specifies the function to run on the server when a client calls the InvokeServer method. Set it from a Script on the server.

Because it is not an event, you set it by assignment rather than with Connect(), and only one function can be assigned. For details on its behavior and caveats, see OnServerInvoke in the Callback section.

#### Code Samples

## Methods

### InvokeClient

This method is used by the server to run the function assigned to a specific client's OnClientInvoke and receive its return values.

A Player argument is required to specify the target client.

This method can only be called from a Script. Calling it from a client LocalScript raises an error.

**Important Notes**

Using this method is not recommended, because it makes the server depend on a response from the client.

* An error raised on the client **propagates to the server** and interrupts the server code.
* If the target client disconnects during the call, an error is raised.
* If the client never returns a value, **the server never resumes.**
* The server also never resumes if no function is assigned to OnClientInvoke.

When you need a result, it is safer to send the request with RemoteEvent's FireClient() and have the client send the result back through a separate RemoteEvent.

#### Parameters

| `Player` Player | <p>This is the Player whose OnClientInvoke will run.</p><p>In the following cases an error is raised at call time, and the function assigned to OnClientInvoke does not run.</p><ul><li>The value is nil</li><li>The value is an Instance that is not a Player</li><li>The value is not an Instance</li><li>The value is a reference to a Player who has already left</li></ul> |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `any` ...       | <p>These are the arguments passed to the function assigned to OnClientInvoke.</p><ul><li>The same delivery limitations as InvokeServer apply.</li></ul>                                                                                                                                                                                                                         |

#### Return

| `Tuple` | <p>These are the values returned by the function assigned to OnClientInvoke.</p><ul><li>Multiple values can be returned at once.</li><li>If the assigned function has no return statement, the caller receives nil.</li></ul> |
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Code Samples

```lua
-- Script
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local S2C_GetSetting = ReplicatedStorage:WaitForChild("S2C_GetSetting")

local function RequestSetting(player, settingKey)
    -- Check that the target Player is still connected right before the call
    if player.Parent ~= Players then
        return
    end

    local Value = S2C_GetSetting:InvokeClient(player, settingKey) -- Passing arguments
    print("[InvokeClient]", player.Name, " / Value : ", Value)
end


-----------------------------------------------------------------------------------
-- LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local S2C_GetSetting = ReplicatedStorage:WaitForChild("S2C_GetSetting")

local function OnGetSetting(settingKey)
    return SettingTable[settingKey]
end
S2C_GetSetting.OnClientInvoke = OnGetSetting
```

### InvokeServer

This method is used by the client to run the function assigned to the server's OnServerInvoke and receive its return values.

This method can only be called from a LocalScript. Calling it from a server Script raises an error.

If no function is assigned to OnServerInvoke, the script that called this method never resumes, and no error or timeout occurs.

If the function assigned to OnServerInvoke throws an error, that error propagates to the calling client, so you can handle it by wrapping the call in pcall().

#### Parameters

| `any` ... | <p>These are the values passed to the function assigned to OnServerInvoke, starting from its second parameter. The first parameter, player, is supplied by the server.</p><ul><li>You can pass basic Luau data types such as number, boolean, string, and table.</li><li>Objects like Instances can also be passed.</li><li>However, not all data types are fully supported, so it's recommended to test how they behave before using them.</li><li>Functions are not delivered. Passing one directly results in nil, and placing one as a table value removes that key entirely.</li><li>Instances that are not replicated, such as those under ServerStorage, are not delivered either.</li><li>A table is passed as a copy, and its metatable is not delivered.</li></ul> |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Return

| `Tuple` | <p>These are the values returned by the function assigned to OnServerInvoke.</p><ul><li>Multiple values can be returned at once.</li><li>If the assigned function has no return statement, the caller receives nil.</li><li>The same delivery limitations that apply to arguments also apply to return values.</li><li>When StreamingEnabled is on, an Instance returned by the server is received as nil if it has not been streamed to the client yet.</li></ul> |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

#### Code Samples

```lua
-- LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local C2S_BuyItem = ReplicatedStorage:WaitForChild("C2S_BuyItem")

local ItemId = 1001
local Amount = 2

local IsSuccess, Balance = C2S_BuyItem:InvokeServer(ItemId, Amount) -- Passing arguments
print("[InvokeServer]", "IsSuccess : ", IsSuccess, " / Balance : ", Balance)


-----------------------------------------------------------------------------------
-- Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local C2S_BuyItem = ReplicatedStorage:WaitForChild("C2S_BuyItem")

local function OnBuyItem(player, itemId, amount)
    print("[OnBuyItem]", player.Name, " / itemId : ", itemId, " / amount : ", amount)
    return true, 500
end
C2S_BuyItem.OnServerInvoke = OnBuyItem
```

## Events

## Callback

### OnServerInvoke

When the InvokeServer method is called on a RemoteFunction instance, the function assigned to OnServerInvoke runs on the server, and the arguments provided during the call are passed along as-is, starting from the function's second parameter.

OnServerInvoke is not an event but a property that holds a function, so it cannot be used with Connect(). Assign the function to it instead.

**Important Notes**

* Only one function can be assigned. If you assign more than once, **only the last assigned function** runs.
* Assigning a value that is not a function does not raise an error at assignment time. The error occurs when InvokeServer is called.
* The first parameter, player, is determined by the server from the request itself, so you can rely on it for permission checks. Everything from the second parameter onward is **sent by the client and cannot be trusted.**
* A client can send a table that looks like an Instance, so check the actual type with typeof().
* NaN passes range checks because every comparison against it is false. Inf passes unless you check for an upper bound.
* If the assigned function yields for a long time, the calling client waits just as long.

#### Parameters

| `Player` Player   | This is the Player of the client that called InvokeServer. It is not a value sent by the client, but one the server determines from the request itself.                                                                                                                                                              |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Tuple` Arguments | <p>These are the arguments provided when InvokeServer was called.</p><ul><li>The engine passes them along without validation, so you have to check their types and value ranges yourself.</li><li>A table received here is a copy, so changes made to it are not reflected in the caller's original table.</li></ul> |

#### Return

| `Tuple` | <p>These are the values delivered to the client that called InvokeServer.</p><ul><li>Multiple values can be returned at once.</li><li>If you omit the return statement, the caller receives nil.</li><li>The same delivery limitations that apply to arguments also apply to return values.</li></ul> |
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Code Samples

```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local C2S_BuyItem = ReplicatedStorage:WaitForChild("C2S_BuyItem")

local function OnBuyItem(player, item, amount)
    -- Check permission
    if not CanPurchase(player) then
        return false
    end

    -- Check type and structure
    if typeof(item) ~= "Instance" or not item:IsA("Tool") then
        return false
    end

    -- Check value range
    if typeof(amount) ~= "number" then
        return false
    end
    if amount ~= amount then -- NaN
        return false
    end
    if math.abs(amount) == math.huge then -- Inf
        return false
    end
    if amount < 1 or amount > 99 then
        return false
    end

    return Purchase(player, item, amount)
end
C2S_BuyItem.OnServerInvoke = OnBuyItem -- Assign the function instead of using Connect
```

### OnClientInvoke

When the InvokeClient method is called on a RemoteFunction instance, the function assigned to OnClientInvoke runs on the target client, and the arguments provided during the call are passed along as-is.

OnClientInvoke is not an event but a property that holds a function, so it cannot be used with Connect(). Assign the function to it instead.

**Important Notes**

* Only one function can be assigned. If you assign more than once, **only the last assigned function** runs.
* An error raised in this function **propagates to the server** that called InvokeClient.
* Assigning a value that is not a function does not raise an error at assignment time. The error occurs when InvokeClient is called, and it also propagates to the server.
* If this function yields without returning a value, the server waits along with it.

#### Parameters

| `Tuple` Arguments | <p>These are the arguments provided when InvokeClient was called. The Player argument is excluded, and everything after it is passed along.</p><ul><li>A table received here is a copy, so changes made to it are not reflected in the caller's original table.</li></ul> |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Return

| `Tuple` | <p>These are the values delivered to the server that called InvokeClient.</p><ul><li>Multiple values can be returned at once.</li><li>If you omit the return statement, the caller receives nil.</li></ul> |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### Code Samples

```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local S2C_GetSetting = ReplicatedStorage:WaitForChild("S2C_GetSetting")

local SettingTable = { Volume = 80, Quality = "High" }

local function OnGetSetting(settingKey)
    return SettingTable[settingKey]
end
S2C_GetSetting.OnClientInvoke = OnGetSetting -- Assign the function instead of using Connect
```

## See also

{% content-ref url="/pages/mfqBcNA4eO76WSB23UO8" %}
[Server-Client Communication](/manual/script-manual/events-and-communication/remoteevent.md)
{% endcontent-ref %}
