Les jeux Roblox sont multijoueurs par défaut, donc tous les jeux communiquent par défaut entre le serveur et les clients connectés des joueurs. Dans le cas le plus simple, à mesure que les joueurs déplacent leurs personnages, certaines propriétés de Humanoid, telles que les états, sont communiquées au serveur, qui transmet cette information à d'autres clients connectés.
Les événements distants et les rappels vous permettent de communiquer à travers la frontière client-serveur :
- RemoteEvents permettent une communication unidirectionnelle (envoi d'une demande et non attente d'une réponse).
- UnreliableRemoteEvents permettent une communication unidirectionnelle pour les données qui changent continuellement ou ne sont pas critiques pour l'état du jeu. Ces événements échangent l'ordre et la fiabilité pour améliorer les performances réseau.
- RemoteFunctions permettent une communication bidirectionnelle (envoi d'une demande et attente jusqu'à ce qu'une réponse soit reçue de la part du destinataire).
Contrairement aux événements bindables, qui ont une utilité plus limitée, les cas d'utilisation pour les événements et fonctions distants sont trop nombreux pour être énumérés :
- Gameplay - Le gameplay de base, comme un joueur atteignant la fin d'un niveau, peut nécessiter un événement distant. Un script client notifie le serveur, et des scripts serveur réinitialisent la position du joueur.
- Vérification serveur - Si un joueur essaie de boire une potion, a-t-il réellement cette potion ? Pour garantir l'équité, le serveur doit être la source de vérité pour un jeu. Un script client peut utiliser un événement distant pour notifier le serveur que le joueur boit une potion, et ensuite les scripts serveur peuvent décider si le joueur possède réellement cette potion et s'il convient d'accorder des avantages.
- Mises à jour de l'interface utilisateur - Alors que l'état du jeu change, les scripts serveur peuvent utiliser des événements distants pour notifier les clients des changements de scores, d'objectifs, etc.
- Achats sur le marché en jeu - Pour un exemple d'implémentation qui utilise des fonctions distantes, voir Achats d'abonnement par invitation.
Référence rapide
Les tableaux suivants servent de référence rapide pour utiliser RemoteEvents et RemoteFunctions afin de communiquer entre le client et le serveur.
| Client → Serveur | |
|---|---|
| Client | RemoteEvent:FireServer(args) |
| Serveur | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
| Serveur → Client | |
| Serveur | RemoteEvent:FireClient(player, args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
| Serveur → Tous les clients | |
| Serveur | RemoteEvent:FireAllClients(args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
Événements distants
Un objet RemoteEvent facilite la communication asynchrone, unidirectionnelle à travers la frontière client-serveur sans attendre une réponse.
Pour créer un nouveau RemoteEvent via la fenêtre Explorer dans Studio :
- Survolez le conteneur dans lequel vous souhaitez insérer le RemoteEvent. Afin de garantir l'accès à la fois au serveur et au client, il doit se trouver dans un endroit où les deux côtés peuvent le voir, comme ReplicatedStorage, bien que dans certains cas, il soit approprié de le stocker dans Workspace ou à l'intérieur d'un Tool.
- Cliquez sur le bouton ⊕ qui apparaît à droite du nom du conteneur et insérez une instance RemoteEvent.
- Renommez l'instance pour décrire son objectif.
Une fois que vous avez créé un RemoteEvent, il peut faciliter une communication unidirectionnelle de client à serveur, de serveur à client, ou du serveur à tous les clients.



Client → serveur
Vous pouvez utiliser un LocalScript pour déclencher un événement sur le serveur en appelant la méthode FireServer() sur un RemoteEvent. Si vous passez des arguments à FireServer(), ils passeront à l'handler de l'événement sur le serveur avec certaines limitations. Notez que le premier paramètre du gestionnaire d'événements sur le serveur est toujours l'objet Player du client qui l'appelle, et des paramètres supplémentaires suivent.
| Client | RemoteEvent:FireServer(args) |
| Serveur | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
Le Script suivant connecte un gestionnaire d'événements à OnServerEvent qui crée une nouvelle Part sur le serveur. Le LocalScript d'accompagnement appelle ensuite FireServer() sur l'instance RemoteEvent avec la Color et la Position désirées pour la pièce.
Connexion d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Obtenez une référence à l'instance de l'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " a déclenché l'événement distant")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- Connecter la fonction à l'événement
remoteEvent.OnServerEvent:Connect(onCreatePart)
Déclenchement de l'événement - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenez une référence à l'instance de l'événement distantlocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Déclencher l'événement distant et passer des arguments supplémentairesremoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
Serveur → client
Vous pouvez utiliser un Script pour déclencher un événement sur un client en appelant la méthode FireClient() sur un RemoteEvent. Le premier argument pour FireClient() est l'objet Player du client auquel vous souhaitez répondre, et des arguments supplémentaires passent au client avec certaines limitations. Notez que le gestionnaire d'événements n'a pas besoin d'inclure l'objet Player comme premier argument car vous pouvez déterminer le joueur sur le client avec Players.LocalPlayer.
| Serveur | RemoteEvent:FireClient(player, args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
Le LocalScript suivant connecte un gestionnaire d'événements à l'événement OnClientEvent. Le Script d'accompagnement écoute alors les joueurs entrants vers le serveur et appelle FireClient() pour chacun avec des données arbitraires.
Connexion d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Obtenez une référence à l'instance de l'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Événement reçu par le joueur", player.Name)
print(maxPlayers, respawnTime)
end
-- Connecter la fonction à l'événement
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Déclenchement de l'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Obtenez une référence à l'instance de l'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Écoutez les joueurs entrants et envoyez un événement distant à chacun
local function onPlayerAdded(player)
print("[Serveur] Déclenchement de l'événement pour le joueur", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Serveur → tous les clients
Vous pouvez utiliser un Script pour déclencher un événement sur tous les clients en appelant la méthode FireAllClients() sur un RemoteEvent. Contrairement à FireClient(), la méthode FireAllClients() ne nécessite pas d'objet Player car elle déclenche l'RemoteEvent pour tous les clients.
| Serveur | RemoteEvent:FireAllClients(args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
Le LocalScript suivant connecte un gestionnaire d'événements à l'événement OnClientEvent qui affiche un temps de compte à rebours restant. Le Script d'accompagnement appelle ensuite FireAllClients() dans une boucle chaque seconde pour déclencher l'RemoteEvent pour tous les clients.
Connexion d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenez une référence à l'instance de l'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Connecter la fonction à l'événement
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Déclenchement de l'événement - Scriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenez une référence à l'instance de l'événement distantlocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local countdown = 5-- Déclencher l'événement distant toutes les secondes jusqu'à ce que le temps expirefor timeRemaining = -1, countdown doremoteEvent:FireAllClients(countdown - timeRemaining)task.wait(1)end
Rappels distants
Un objet RemoteFunction facilite la communication synchrone, bidirectionnelle à travers la frontière client-serveur. L'expéditeur d'une fonction distante attendra jusqu'à ce qu'il reçoive une réponse du destinataire.
Pour créer une nouvelle RemoteFunction via la fenêtre Explorer dans Studio :
- Survolez le conteneur dans lequel vous souhaitez insérer le RemoteFunction. Afin de garantir l'accès à la fois au serveur et au client, il doit se trouver dans un endroit où les deux côtés peuvent le voir, tel que ReplicatedStorage, bien que dans certains cas, il soit approprié de le stocker dans Workspace ou à l'intérieur d'un Tool.
- Cliquez sur le bouton ⊕ qui apparaît à droite du nom du conteneur et insérez une instance RemoteFunction.
- Renommez l'instance pour décrire son objectif.
Une fois que vous avez créé une RemoteFunction, elle peut faciliter une communication bidirectionnelle entre client et serveur ou entre serveur et client.


Client → serveur → client
Vous pouvez utiliser un LocalScript pour appeler une fonction sur le serveur en appelant la méthode InvokeServer() sur un RemoteFunction. Contrairement à un événement distant, le LocalScript qui invoque la RemoteFunction attend jusqu'à ce que le rappel retourne. Les arguments que vous passez à InvokeServer() passent au rappel OnServerInvoke de la RemoteFunction avec certaines limitations. Notez que si vous définissez plusieurs rappels pour la même RemoteFunction, seule la dernière définition sera exécutée.
| Client | RemoteFunction:InvokeServer(args) |
| Serveur | RemoteFunction.OnServerInvoke = function(player, args) |
Le Script suivant définit la fonction de rappel via OnServerInvoke et retourne la Part demandée à travers sa valeur de return. Le LocalScript d'accompagnement appelle ensuite InvokeServer() avec des arguments supplémentaires définissant la couleur et la position de la pièce demandée.
Connexion de rappel - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Obtenez une référence à l'instance de la fonction distante
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Fonction de rappel
local function createPart(player, partColor, partPosition)
print(player.Name .. " a demandé une nouvelle pièce")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Définir la fonction comme rappel de la fonction distante
remoteFunction.OnServerInvoke = createPart
Invocation de l'événement - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenez une référence à l'instance de la fonction distantelocal remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")-- Passer une couleur et une position lors de l'invocation du rappellocal newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))-- Afficher la référence de la pièce retournéeprint("Le serveur a créé la pièce demandée :", newPart)
Serveur → client → serveur
Vous pouvez utiliser un Script pour appeler une fonction sur le client en appelant la méthode InvokeClient() sur un RemoteFunction, mais cela comporte des risques sérieux, comme suit :
- Si le client génère une erreur, le serveur génère également l'erreur.
- Si le client se déconnecte pendant qu'il est invoqué, InvokeClient() génère une erreur.
- Si le client ne retourne aucune valeur, le serveur attend indéfiniment.
Pour des actions qui ne nécessitent pas de communications bidirectionnelles, comme mettre à jour une GUI, utilisez un RemoteEvent et communiquez de serveur à client.
Limitations des arguments
Lorsque vous déclenchez un RemoteEvent ou invoquez une RemoteFunction, cela transmet tous les arguments que vous passez avec l'événement ou à la fonction de rappel. Tout type d'objet Roblox tel qu'un Enum, une Instance, ou d'autres peuvent être passés, ainsi que des types Luau comme des nombres, des chaînes de caractères et des booléens, bien que vous deviez explorer attentivement les limitations suivantes.
Indices non-string
Si des indices d'une table passée sont de types non-string comme une Instance, userdata, ou fonction, Roblox convertit automatiquement ces indices en chaînes.
Connexion d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> string
end
end
-- Connecter la fonction à l'événement
remoteEvent.OnClientEvent:Connect(onEventFire)
Déclenchement de l'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Écoutez les joueurs entrants et envoyez un événement distant à chacun
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Fonctions passées
Les fonctions incluses comme arguments pour un RemoteEvent ou RemoteFunction ne seront pas répliquées à travers la frontière client-serveur, ce qui rend impossible le passage de fonctions à distance. Le résultat de l'argument côté récepteur sera nil.
Connexion d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nil
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Déclenchement de l'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Bonjour le monde !")
end
-- Déclencher un événement distant avec une fonction comme argument
remoteEvent:FireAllClients(testFunction)
Indexation de table
Si vous passez une table de données, ne passez pas une table mixte de clés numériques et string. Au lieu de cela, passez une table qui consiste entièrement en paires clé-valeur (dictionnaire) ou entièrement d'indices numériques.
Connexion d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(player, passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Épée
--> 2 = Arc
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Connecter la fonction à l'événement
remoteEvent.OnServerEvent:Connect(onEventFire)
Déclenchement de l'événement - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Table indexée numériquementlocal inventoryData = {"Épée", "Arc"}-- Table dictionnairelocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}remoteEvent:FireServer(inventoryData)remoteEvent:FireServer(characterData)
Identités de table
Les tables passées comme arguments aux événements distants ou rappels sont copiées, ce qui signifie qu'elles ne seront pas exactement équivalentes à celles fournies lors du déclenchement de l'événement ou de l'invocation du rappel. Les tables retournées à l'invocateur ne seront pas non plus exactement équivalentes à celles fournies. Vous pouvez le démontrer en exécutant le script suivant sur une RemoteFunction et en observant comment les identités de table diffèrent.
Connexion de rappel - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Fonction de rappel
local function returnTable(player, passedTable)
-- Afficher l'identité de la table lors de l'invocation
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Définir la fonction comme rappel de la fonction distante
remoteFunction.OnServerInvoke = returnTable
Invocation de l'événement - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")local inventoryData = {"Épée", "Arc"}-- Afficher l'identité de la table originaleprint(tostring(inventoryData)) --> table: 0x059bcdbb2b576549local invokeReturn = remoteFunction:InvokeServer(inventoryData)-- Afficher l'identité de la table lors du retourprint(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
Métatables
Si une table a une métatable, toutes les informations de métatables sont perdues lors du transfert. Dans l'exemple de code suivant, la propriété NumWheels fait partie de la métatable de Car. Lorsque le serveur reçoit la table suivante, la table truck a la propriété Name mais pas la propriété NumWheels.
Connexion d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "MyTruck"}
end
-- Connecter la fonction à l'événement
remoteEvent.OnServerEvent:Connect(onEvent)
Déclenchement de l'événement - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- Déclencher un événement avec une table incluant une métatableremoteEvent:FireServer(truck)
Instances non-répliquées
Si un RemoteEvent ou RemoteFunction passe une valeur qui n'est visible que pour l'expéditeur, Roblox ne la réplique pas à travers la frontière client-serveur et passe nil à la place de la valeur. Par exemple, si un Script passe un descendant de ServerStorage, le client écoutant l'événement recevra une valeur nil car cet objet n'est pas répliquable pour le client.
Déclenchement de l'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sera reçu comme "nil" car le client ne peut pas accéder à ServerStorage
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)
De même, si vous créez une pièce dans un LocalScript et essayez de la passer à un Script, le serveur verra nil car la pièce n'est pas répliquable pour le serveur.
Déclenchement de l'événement - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local Workspace = game:GetService("Workspace")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Sera reçu comme "nil" car le serveur ne connaît pas cette piècelocal clientPart = Instance.new("Part")clientPart.Parent = WorkspaceremoteEvent:FireServer(clientPart)