Client vs Serveur

Objectif : Comprendre l'architecture réseau de Roblox et apprendre à faire communiquer le client (joueur) et le serveur de manière sécurisée.

Le Réseau dans Roblox

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 !

1. Client vs Serveur : Qui Fait Quoi ?

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).

SERVEUR

  • Gère les données importantes (coins, XP, inventaire)
  • Fait les calculs sensibles
  • Fait autorité sur ce qui se passe
  • Scripts dans ServerScriptService
  • UN seul serveur pour tous les joueurs

CLIENT

  • Affiche l'interface (GUI)
  • Gère les inputs (clavier, souris)
  • Joue les sons/effets locaux
  • Scripts dans StarterPlayerScripts
  • UN client par joueur

🚨 Règle d'Or de la Sécurité

Ne 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.

2. Les Types de Scripts

Roblox propose différents types de scripts selon où tu veux exécuter le code :

Script

S'exécute côté SERVEUR.

Mettre dans ServerScriptService ou attaché aux objets.

LocalScript

S'exécute côté CLIENT du joueur.

Mettre dans StarterPlayerScripts ou StarterGui.

ModuleScript

Code réutilisable (bibliothèque).

Peut être utilisé par Script ou LocalScript.

ReplicatedStorage

Dossier partagé visible par client ET serveur.

Idéal pour les RemoteEvents et modules communs.

📚 Documentation Officielle Roblox

Pour approfondir tes connaissances sur l'architecture Client-Serveur :

3. Communiquer : RemoteEvents

Les RemoteEvents sont le pont entre client et serveur. Ils permettent d'envoyer des messages dans les deux sens.

3.1 Client ? Serveur (FireServer)

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)

3.2 Serveur ? Client (FireClient)

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)
Récapitulatif
DirectionMéthodeÉcoute
Client ? Serveur:FireServer().OnServerEvent
Serveur ? Client:FireClient().OnClientEvent
Serveur ? Tous:FireAllClients().OnClientEvent

4. RemoteFunctions (Appels avec Réponse)

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
    }
end

⚠️ Attention aux RemoteFunctions

N'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.

💻 Sandbox Luau
Simulateur v2.0
1 2 3 4 5 6 7 8 9 10
👉 Simule des échanges client/serveur...

Quiz : Client vs Serveur

5 questions pour valider tes acquis

1. Où doit-on gérer l'argent des joueurs ?

  • Côté Client
  • Côté Serveur
  • Les deux
  • Ça n'a pas d'importance

2. Quel type de script s'exécute sur l'ordinateur du joueur ?

  • Script
  • LocalScript
  • ModuleScript
  • ServerScript

3. Quelle méthode envoie un message du client vers le serveur ?

  • :FireServer()
  • :FireClient()
  • :SendToServer()
  • :Connect()

4. Dans quel dossier met-on les RemoteEvents ?

  • ServerStorage
  • ReplicatedStorage
  • Workspace
  • StarterPack

5. Pourquoi ne faut-il pas utiliser :InvokeClient() depuis le serveur ?

  • Ça ne fonctionne pas
  • C'est trop lent
  • Un joueur pourrait bloquer le serveur
  • Ça utilise trop de mémoire
Exercice Pratique

Configure le RemoteEvent

Place les éléments dans le bon ordre pour créer un système client-serveur !

15-50 Points
OnServerEvent:Connect
Réception serveur
Créer RemoteEvent
Dans ReplicatedStorage
:FireServer()
Envoie du client
Référencer l'event
local remoteEvent = ...
1
Première étape...
2
Préparation...
3
Communication...
4
Réaction...
👥
Étape 7/10

Système Multijoueur

En mode multijoueur, chaque nouveau joueur apporte des ressources bonus ! Chaque visiteur qui rejoint = +10 ⚡ ! Plus vous êtes nombreux, plus vous survivez longtemps !

1
2
3
4
5
6
7
8
9
10
Prérequis

Modules 1 à 6 complétés (RemoteEvents, Client/Serveur)

Construction du Compteur Multijoueur

1
Crée le Panneau

Crée une Part avec un SurfaceGui pour afficher le compteur.

Part Size6, 4, 0.5
Nom"PanneauVisiteurs"
EnfantsSurfaceGui ? TextLabel
2
Crée le RemoteEvent

Dans ReplicatedStorage, crée un RemoteEvent et nomme-le "NouveauVisiteur".

3
Script Serveur

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)
4
Script Client (LocalScript)

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 !")
Bonus : Record de Visiteurs

Ajoute une variable recordMax et affiche "🏆 Record: X" quand le compteur dépasse le record !

Système multijoueur actif !

Prochaine étape → Module 8 : Système d'Inventaire

📊
🚀 SURVIE SPATIALE - Étape 7/10

HUD de la Station

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 !

1
2
3
4
5
6
7
8
9
10
Contexte : Ta station fonctionne ! Mais le joueur ne voit pas ses ressources. Il faut un HUD (Head-Up Display) comme dans les vrais jeux de survie !
1
📐 Architecture du Système GUI

Le HUD sera visible par chaque joueur individuellement. Voici la structure complète :

▼ StarterGui
▼ 📺 HUD_Station
📊 BarreEnergie
🏷️ TextLabel
📦 BarreRemplissage
📊 BarreOxygene
💎 CompteurCristaux
📜 HUD_Client (LocalScript)
▼ ReplicatedStorage
📡 MiseAJourHUD (RemoteEvent)
▼ ServerScriptService
📜 GestionnaireRessources
Client vs Serveur : Le serveur stocke les vraies valeurs et les envoie au client via RemoteEvent. Le client affiche seulement !
2
📺 Créer le ScreenGui dans StarterGui

Va dans StarterGui, clic droit → Insert Object → ScreenGui. Renomme-le HUD_Station.

NameHUD_Station
ResetOnSpawnfalse
IgnoreGuiInsettrue
ResetOnSpawn = false garde le HUD même quand le joueur meurt et respawn !
3
⚡ Créer la Barre d'Énergie

Dans HUD_Station, crée un Frame pour le fond de la barre :

Frame "BarreEnergie" (conteneur)

NameBarreEnergie
Position{0.02, 0}, {0.05, 0}
Size{0.2, 0}, {0.03, 0}
BackgroundColor3[30, 30, 40]
BorderSizePixel0

Frame "Remplissage" (dans BarreEnergie)

NameRemplissage
Position{0, 0}, {0, 0}
Size{0.5, 0}, {1, 0}
BackgroundColor3[0, 255, 127]

TextLabel "Label" (dans BarreEnergie)

NameLabel
Size{1, 0}, {1, 0}
Text⚡ 50/100
TextColor3[255, 255, 255]
BackgroundTransparency1
4
📡 Créer le RemoteEvent

Dans ReplicatedStorage, crée un RemoteEvent nommé MiseAJourHUD. C'est le "canal" de communication.

RemoteEvent : Le serveur utilisera :FireClient(joueur, données) pour envoyer les ressources à chaque joueur !
5
📜 Script Serveur - GestionnaireRessources

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() end
6
📜 LocalScript - HUD_Client

Cré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!")
Concepts du cours appliqués :
FireClient(joueur, data) → Serveur envoie au client
OnClientEvent:Connect() → Client reçoit
UDim2.new() → Positionnement GUI relatif
• Table de données → Envoyer plusieurs valeurs d'un coup
7
🎮 Tester le HUD

Lance le jeu avec F5 et observe :

  • 📊 La barre d'énergie apparaît en haut à gauche
  • ⬇️ Elle diminue progressivement (consommation)
  • 🎨 La couleur change : vert → orange → rouge
  • 🔢 Le texte affiche les valeurs exactes
Bonus : Complète le HUD !
  • Ajoute une barre d'oxygène (bleue) en dessous
  • Ajoute un compteur de cristaux avec icône 💎
  • Fais clignoter la barre quand une ressource est critique !
  • Utilise UICorner pour arrondir les barres
📊

HUD de la station opérationnel !

Le joueur voit maintenant ses ressources en temps réel ! → Module 8 : Animations avec TweenService