Objectif : Comprendre l'architecture réseau de Roblox et apprendre à faire communiquer le client (joueur) et le serveur de manière sécurisée.
Pourquoi c'est crucial de comprendre
Dans Roblox, le code peut tourner à deux endroits différents : sur l'ordinateur du joueur (Client) ou sur les serveurs Roblox (Serveur). Savoir où ton code s'exécute est essentiel pour la sécurité et le bon fonctionnement de ton jeu !
Imagine ton jeu comme un restaurant. Le serveur c'est la cuisine (prépare tout), le client c'est le client du restaurant (affiche et interagit).
ServerScriptServiceStarterPlayerScriptsNe fais JAMAIS confiance au client ! Un joueur peut modifier son propre client. Toute logique importante (argent, dégâts, inventaire) doit être calculée côté SERVEUR.
Roblox propose différents types de scripts selon où tu veux exécuter le code :
S'exécute côté SERVEUR.
Mettre dans ServerScriptService ou attaché aux objets.
S'exécute côté CLIENT du joueur.
Mettre dans StarterPlayerScripts ou StarterGui.
Code réutilisable (bibliothèque).
Peut être utilisé par Script ou LocalScript.
Dossier partagé visible par client ET serveur.
Idéal pour les RemoteEvents et modules communs.
Pour approfondir tes connaissances sur l'architecture Client-Serveur :
Les RemoteEvents sont le pont entre client et serveur. Ils permettent d'envoyer des messages dans les deux sens.
Le joueur veut acheter quelque chose ? Le client envoie une demande au serveur.
📱 LocalScript (Client)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local acheterEvent = ReplicatedStorage:WaitForChild("AcheterItem")
-- Quand le joueur clique sur le bouton "Acheter"
boutonAcheter.MouseButton1Click:Connect(function()
local itemVoulu = "Epee"
acheterEvent:FireServer(itemVoulu) -- Envoie au serveur
end)🖥️ Script (Serveur)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local acheterEvent = ReplicatedStorage:WaitForChild("AcheterItem")
acheterEvent.OnServerEvent:Connect(function(joueur, itemVoulu)
print(joueur.Name .. " veut acheter : " .. itemVoulu)
-- Vérifie si le joueur a assez d'argent (CÔTÉ SERVEUR !)
if joueur.leaderstats.Coins.Value >= 100 then
joueur.leaderstats.Coins.Value -= 100
-- Donne l'item...
print("Achat réussi !")
else
print("Pas assez de coins !")
end
end)Le serveur veut envoyer une notification à un joueur spécifique :
🖥️ Script (Serveur)
local notifEvent = ReplicatedStorage:WaitForChild("Notification")
-- Envoie une notif à UN joueur
notifEvent:FireClient(joueur, "Tu as gagné 100 XP !")
-- Envoie à TOUS les joueurs
notifEvent:FireAllClients("Un boss est apparu !")📱 LocalScript (Client)
local notifEvent = ReplicatedStorage:WaitForChild("Notification")
notifEvent.OnClientEvent:Connect(function(message)
print("Notification : " .. message)
-- Affiche dans l'interface...
end)| Direction | Méthode | Écoute |
|---|---|---|
| Client ? Serveur | :FireServer() | .OnServerEvent |
| Serveur ? Client | :FireClient() | .OnClientEvent |
| Serveur ? Tous | :FireAllClients() | .OnClientEvent |
Les RemoteFunctions permettent d'envoyer une requête ET d'attendre une réponse. Comme un appel téléphonique plutôt qu'un SMS.
Demander des données au serveur
-- CLIENT : Demande les stats du joueur
local getStats = ReplicatedStorage:WaitForChild("GetStats")
local mesStats = getStats:InvokeServer() -- Attend la réponse
print("J'ai " .. mesStats.coins .. " coins")
-- SERVEUR : Répond à la demande
getStats.OnServerInvoke = function(joueur)
return {
coins = joueur.leaderstats.Coins.Value,
level = joueur.leaderstats.Level.Value
}
endN'utilise JAMAIS :InvokeClient() depuis le serveur ! Un joueur malveillant pourrait bloquer ton serveur en ne répondant jamais. Préfère les RemoteEvents dans ce sens.
5 questions pour valider tes acquis
En mode multijoueur, chaque nouveau joueur apporte des ressources bonus ! Chaque visiteur qui rejoint = +10 ⚡ ! Plus vous êtes nombreux, plus vous survivez longtemps !
Modules 1 à 6 complétés (RemoteEvents, Client/Serveur)
Crée une Part avec un SurfaceGui pour afficher le compteur.
Dans ReplicatedStorage, crée un RemoteEvent et nomme-le "NouveauVisiteur".
Crée un Script dans ServerScriptService :
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local nouveauVisiteur = ReplicatedStorage:WaitForChild("NouveauVisiteur")
local compteur = 0
local panneau = workspace:FindFirstChild("PanneauVisiteurs")
local textLabel = panneau.SurfaceGui.TextLabel
-- Quand un client signale sa visite
nouveauVisiteur.OnServerEvent:Connect(function(player)
compteur = compteur + 1
textLabel.Text = "Visiteurs: " .. compteur
print("👤✅ " .. player.Name .. " a visité ! Total: " .. compteur)
end)Crée un LocalScript dans StarterPlayerScripts :
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local nouveauVisiteur = ReplicatedStorage:WaitForChild("NouveauVisiteur")
-- Attendre que le joueur soit chargé
task.wait(2)
-- Signaler la visite au serveur
nouveauVisiteur:FireServer()
print("📤 Visite signalée au serveur !")Ajoute une variable recordMax et affiche "🏆 Record: X" quand le compteur dépasse le record !
Prochaine étape → Module 8 : Système d'Inventaire
Crée une interface utilisateur (GUI) qui affiche en temps réel l'état de la station : ⚡ Énergie, 💎 Cristaux, et 🫁 Oxygène. Utilise la communication Client/Serveur !
Le HUD sera visible par chaque joueur individuellement. Voici la structure complète :
Va dans StarterGui, clic droit → Insert Object → ScreenGui. Renomme-le HUD_Station.
Dans HUD_Station, crée un Frame pour le fond de la barre :
Dans ReplicatedStorage, crée un RemoteEvent nommé MiseAJourHUD. C'est le "canal" de communication.
:FireClient(joueur, données) pour envoyer les ressources à chaque joueur !Crée un Script dans ServerScriptService. Il envoie les données aux clients :
-- GestionnaireRessources.lua (ServerScriptService) local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local miseAJourHUD = ReplicatedStorage:WaitForChild("MiseAJourHUD") -- Ressources de la station (partagées) local ressources = { energie = 50, energieMax = 100, oxygene = 80, oxygeneMax = 100, cristaux = 0 } -- FONCTION : Envoyer les données à tous les joueurs local function envoyerMiseAJour() for _, joueur in pairs(Players:GetPlayers()) do miseAJourHUD:FireClient(joueur, ressources) end end -- Simulation : ressources changent while true do task.wait(1) -- Consommation automatique ressources.energie = math.max(0, ressources.energie - 1) ressources.oxygene = math.max(0, ressources.oxygene - 0.5) -- Envoyer les nouvelles valeurs envoyerMiseAJour() endCrée un LocalScript dans le ScreenGui HUD_Station. Il reçoit les données et met à jour l'affichage :
-- HUD_Client.lua (LocalScript dans HUD_Station) local ReplicatedStorage = game:GetService("ReplicatedStorage") local miseAJourHUD = ReplicatedStorage:WaitForChild("MiseAJourHUD") -- Références aux éléments GUI local hud = script.Parent local barreEnergie = hud:WaitForChild("BarreEnergie") local remplissageEnergie = barreEnergie:WaitForChild("Remplissage") local labelEnergie = barreEnergie:WaitForChild("Label") -- FONCTION : Mettre à jour l'affichage local function updateHUD(ressources) -- Énergie local pctEnergie = ressources.energie / ressources.energieMax remplissageEnergie.Size = UDim2.new(pctEnergie, 0, 1, 0) labelEnergie.Text = "⚡ " .. math.floor(ressources.energie) .. "/" .. ressources.energieMax -- Changer la couleur selon le niveau if pctEnergie > 0.5 then remplissageEnergie.BackgroundColor3 = Color3.fromRGB(0, 255, 127) elseif pctEnergie > 0.25 then remplissageEnergie.BackgroundColor3 = Color3.fromRGB(255, 165, 0) else remplissageEnergie.BackgroundColor3 = Color3.fromRGB(255, 50, 50) end end -- ÉVÉNEMENT : Recevoir les données du serveur miseAJourHUD.OnClientEvent:Connect(function(ressources) updateHUD(ressources) end) print("📊 HUD prêt à recevoir les données!")FireClient(joueur, data) → Serveur envoie au clientOnClientEvent:Connect() → Client reçoitUDim2.new() → Positionnement GUI relatifLance le jeu avec F5 et observe :
Le joueur voit maintenant ses ressources en temps réel ! → Module 8 : Animations avec TweenService