← Retour LearnBloxLearnBlox

RemoteEvents — Client ↔ Serveur

Module 10

Roblox sépare strictement le serveur (l'autorité, partagée par tous les joueurs) et le client (l'écran de chaque joueur). Les RemoteEvents et RemoteFunctions sont les ponts qui leur permettent de communiquer : un clic côté client demande au serveur d'agir, le serveur notifie les clients d'un changement.

La règle d'or de la sécurité Roblox tient ici : le serveur ne doit jamais faire confiance au client. Un RemoteEvent transmet une intention ; c'est au serveur de vérifier qu'elle est légitime. Un RemoteEvent est unidirectionnel (on envoie, on n'attend pas de réponse), une RemoteFunction attend une valeur en retour.

🗺️ Architecture Client / Serveur
EmplacementType de scriptAccès
ServerScriptServiceScript (Server)Serveur uniquement
StarterPlayerScriptsLocalScript (Client)Client uniquement
ReplicatedStorageModuleScript / RemoteEventServeur + Client
⚠️ Le client ne peut jamais modifier les données du serveur directement — il doit passer par un RemoteEvent !
📡 Client → Serveur (FireServer)
-- Setup : créer le RemoteEvent dans ReplicatedStorage
-- (ou via Studio)

-- LocalScript (client)
local RS = game:GetService("ReplicatedStorage")
local event = RS:WaitForChild("MonEvent")

-- Envoyer des données au serveur
event:FireServer("acheter", 50)

-- Script serveur (ServerScriptService)
event.OnServerEvent:Connect(function(plr, action, montant)
    print(plr.Name, action, montant)
    -- plr est automatiquement le 1er paramètre
end)
📡 Serveur → Client (FireClient)
-- Script serveur → un client spécifique
local RS = game:GetService("ReplicatedStorage")
local event = RS:WaitForChild("MonEvent")

event:FireClient(plr, "bienvenue", 100)

-- Script serveur → TOUS les clients
event:FireAllClients("annonce", "Partie démarrée !")

-- LocalScript (réception)
event.OnClientEvent:Connect(function(type, data)
    print(type, data)
end)
🔁 RemoteFunction (retour)
-- RemoteFunction : attend une réponse
local RF = RS:WaitForChild("MaFunction")

-- Serveur : définit le callback
RF.OnServerInvoke = function(plr, question)
    if question == "score" then
        return 250  -- valeur retournée
    end
end

-- Client : appel synchrone (attend)
local monScore = RF:InvokeServer("score")
print("Score : " .. monScore)
🛡️ Règles de sécurité
RèglePourquoi
Toujours valider côté serveurLe client peut envoyer n'importe quoi
Ne jamais faire confiance aux données clientHackers/exploits
Vérifier le joueur plrS'assurer qu'il peut faire l'action
Limiter la fréquence (debounce)Éviter le spam d'events
-- ✅ Toujours valider
event.OnServerEvent:Connect(function(plr, montant)
    montant = math.clamp(tonumber(montant) or 0, 0, 100)
    -- montant est sûr maintenant
end)
📦 Créer un RemoteEvent par script
-- Script serveur (crée une seule fois)
local RS = game:GetService("ReplicatedStorage")

local function creerEvent(nom)
    if RS:FindFirstChild(nom) then
        return RS[nom]
    end
    local ev = Instance.new("RemoteEvent")
    ev.Name   = nom
    ev.Parent = RS
    return ev
end

local buyEvent  = creerEvent("BuyItem")
local chatEvent = creerEvent("ChatMsg")
✅ Bonnes pratiques & erreurs fréquentes
  • Valide TOUT côté serveur : un joueur peut envoyer n'importe quelle donnée dans un RemoteEvent. Vérifie les distances, les droits, les montants.
  • RemoteEvent pour notifier, RemoteFunction pour interroger : n'utilise une RemoteFunction que si tu as besoin d'une réponse.
  • Range tes Remotes dans un dossier de ReplicatedStorage : c'est le seul endroit accessible serveur ET client.
  • Méfie-toi des RemoteFunction côté client : si le client ne répond pas, le serveur peut rester bloqué. Préfère un RemoteEvent quand c'est possible.