Événements distants et rappels

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Les jeux Roblox sont multijoueurs par défaut, donc tous les jeux communiquent intrinsèquement entre le serveur et les clients connectés des joueurs. Dans le cas le plus simple, lorsque 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 requête et non attente d'une réponse).
  • UnreliableRemoteEvents permettent une communication unidirectionnelle pour des données qui changent continuellement ou qui 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 requête et attente jusqu'à ce qu'une réponse soit reçue du destinataire).

Contrairement aux événements bindables, qui ont une utilité plus limitée, les cas d'utilisation des événements et fonctions distants sont trop nombreux pour être listés :

  • Gameplay - Le gameplay de base, tel qu'un joueur atteignant la fin d'un niveau, peut nécessiter un événement distant. Un script client notifie le serveur, et les 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, puis les scripts serveur peuvent décider si le joueur a réellement cette potion et s'il faut lui conférer des avantages.
  • Mises à jour de l'interface utilisateur - À mesure 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 invite.

Référence rapide

Les tableaux suivants servent de référence rapide sur la façon d'utiliser RemoteEvents et RemoteFunctions pour communiquer entre le client et le serveur.

Client → Serveur
ClientRemoteEvent:FireServer(args)
ServeurRemoteEvent.OnServerEvent:Connect(function(player, args))
Serveur → Client
ServeurRemoteEvent:FireClient(player, args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))
Serveur → Tous les Clients
ServeurRemoteEvent:FireAllClients(args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Événements distants

Un objet RemoteEvent facilite la communication asynchrone, unidirectionnelle à travers la frontière client-serveur sans attendre de réponse.

Pour créer un nouvel RemoteEvent via la fenêtre Explorer dans Studio :

  1. Survolez le conteneur dans lequel vous souhaitez insérer le RemoteEvent. Pour garantir l'accès à la fois au serveur et au client, il doit être 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.
  2. Cliquez sur le bouton ⊕ qui apparaît à droite du nom du conteneur et insérez une instance RemoteEvent.
  3. Renommez l'instance pour décrire son but.

Une fois que vous avez créé un RemoteEvent, il peut faciliter la communication unidirectionnelle de client à serveur, de serveur à client, ou du serveur à tous les clients.

Client → Serveur
Serveur → Client
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 sont transmis au gestionnaire d'événements 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.

ClientRemoteEvent:FireServer(args)
ServeurRemoteEvent.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 accompagnant appelle ensuite FireServer() sur l'instance RemoteEvent avec la Color et la Position souhaitées pour la pièce.

Connexion d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Obtenir une référence à l'instance d'é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 d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenir une référence à l'instance d'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Déclencher l'événement distant et passer des arguments supplémentaires
remoteEvent: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 à l'événement, et des arguments supplémentaires sont transmis 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.

ServeurRemoteEvent:FireClient(player, args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Le LocalScript suivant connecte un gestionnaire d'événements à l'événement OnClientEvent. Le Script accompagnant écoute ensuite les joueurs entrants sur 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")
-- Obtenir une référence à l'instance d'é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 d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Obtenir une référence à l'instance d'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Écouter les joueurs entrants et dispatcher l'é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 à tous les clients.

ServeurRemoteEvent:FireAllClients(args)
ClientRemoteEvent.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 accompagnant 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")
-- Obtenir une référence à l'instance d'é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 d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenir une référence à l'instance d'événement distant
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Déclencher l'événement distant chaque seconde jusqu'à expiration du temps
for timeRemaining = -1, countdown do
remoteEvent: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 :

  1. Survolez le conteneur dans lequel vous souhaitez insérer le RemoteFunction. Pour garantir l'accès à la fois au serveur et au client, il doit être 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.
  2. Cliquez sur le bouton ⊕ qui apparaît à droite du nom du conteneur et insérez une instance RemoteFunction.
  3. Renommez l'instance pour décrire son but.

Une fois que vous avez créé un RemoteFunction, il peut faciliter la communication bidirectionnelle entre client et serveur ou entre serveur et client.

Client → Serveur → Client
Serveur → Client → Serveur

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 le RemoteFunction attend jusqu'à ce que le rappel retourne. Les arguments que vous passez à InvokeServer() sont transmis au rappel OnServerInvoke du RemoteFunction avec certaines limitations. Notez que si vous définissez plusieurs rappels pour le même RemoteFunction, seule la dernière définition s'exécutera.

ClientRemoteFunction:InvokeServer(args)
ServeurRemoteFunction.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 accompagnant 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")
-- Obtenir une référence à l'instance de 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 d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenir une référence à l'instance de fonction distante
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Passer une couleur et une position lors de l'invocation du rappel
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Afficher la référence de la pièce retournée
print("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 pas de valeur, le serveur attend indéfiniment.

Pour des actions qui ne nécessitent pas de communications bidirectionnelles, telles que la mise à jour d'une interface utilisateur, utilisez un RemoteEvent et communiquez du serveur au client.

Garanties de livraison

Chaque type distant fait des promesses différentes sur la question de savoir si un message arrive et dans quel ordre. Ces promesses ne s'appliquent qu'à une seule connexion dans une seule direction, c'est-à-dire du serveur à un client spécifique, ou d'un client spécifique au serveur.

RemoteEvents

RemoteEvents sont fiables et ordonnés :

  • Si un message est perdu en transit, Roblox le retransmet jusqu'à ce qu'il arrive, tant que le destinataire reste connecté.
  • Les messages arrivent dans l'ordre où vous les déclenchez, y compris à travers différents instances de RemoteEvent. Par exemple, si le serveur déclenche l'événement A, puis B, puis A à nouveau pour le même client, ce client reçoit A, B, A. Cela s'applique que vous utilisiez FireClient() ou FireAllClients().
  • Si un client déclenche des événements plus rapidement que la limite de throttling, le serveur traite les événements excédentaires plus tard au lieu de les abandonner, et ils conservent leur ordre.

Un message fiable et ordonné peut néanmoins échouer à atteindre votre code dans les cas suivants :

  • Aucun gestionnaire n'est connecté. Si rien n'est connecté à OnServerEvent ou OnClientEvent lorsque le message arrive, Roblox le met en file d'attente et le livre, dans l'ordre, dès qu'un gestionnaire se connecte. La file d'attente est limitée en nombre et en mémoire. Une fois qu'elle est pleine, Roblox abandonne les messages supplémentaires et enregistre une erreur Remote event invocation dans la fenêtre Output.
  • Le destinataire se déconnecte. Les messages qui n'ont pas été livrés lorsqu'un client quitte sont perdus.

L'ordre s'applique au moment où chaque gestionnaire commence, et non à quand il se termine. Si un gestionnaire attend, par exemple en appelant task.wait() ou WaitForChild(), Roblox peut commencer à traiter le message suivant avant que le gestionnaire précédent ne reprenne.

RemoteFunctions

RemoteFunctions envoient des invocations et des réponses de manière fiable, donc Roblox retransmet les messages perdus tant que les deux côtés restent connectés. Comme InvokeServer() et InvokeClient() attendent jusqu'à ce qu'une réponse arrive, un seul fil ne peut pas avoir plus d'une invocation en vol. Des fils séparés peuvent invoquer en même temps, cependant, et si un rappel attend, les réponses peuvent revenir dans un ordre différent de celui dans lequel les invocations ont été envoyées.

Si aucun rappel n'est assigné à OnServerInvoke ou OnClientInvoke, Roblox met en file d'attente les invocations jusqu'à ce qu'un soit. Cette file d'attente a les mêmes types de limites que la file d'attente RemoteEvent.

UnreliableRemoteEvents

UnreliableRemoteEvents ne garantissent ni la livraison ni l'ordre. Ils n'ont également aucune relation d'ordre avec RemoteEvents ou RemoteFunctions. Roblox peut abandonner un message dans l'un des cas suivants, sans le renvoyer :

  • Le message est perdu en transit.
  • Le réseau est congestionné et le message attend trop longtemps pour être envoyé.
  • La charge utile est supérieure à 1 000 octets.
  • Le client déclenche plus rapidement que la limite de throttling. Contrairement à un RemoteEvent, le serveur abandonne les messages excédentaires au lieu de les retarder.
  • Rien n'est connecté à OnServerEvent ou OnClientEvent lorsque le message arrive. Contrairement à un RemoteEvent, Roblox abandonne immédiatement le message au lieu de le mettre en file d'attente.

Roblox n'attend également pas qu'un message précédent arrive avant de traiter un message ultérieur, donc les messages peuvent arriver dans le désordre. Si l'ordre est important, incluez un horodatage ou un numéro de séquence dans chaque message et ignorez les messages plus anciens que le dernier que vous avez traité.

Limites de throttling et de taille

Les messages du client au serveur sont soumis à une limite de taux que chaque type distant partage entre toutes ses instances. Pour les limites actuelles, voir la section Throttling de RemoteEvent et les limites de charge utile dans UnreliableRemoteEvent.

Limitations des arguments

Lorsque vous déclenchez un RemoteEvent ou invoquez un RemoteFunction, il 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, Instance, ou d'autres peut être passé, ainsi que des types Luau tels que des nombres, des chaînes et des booléens, bien que vous deviez explorer attentivement les limitations suivantes.

Indices non-chaînes

Si des indices d'une table passée sont de types non-chaînes tels qu'un Instance, userdata, ou function, 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 d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Écouter les joueurs entrants et dispatcher l'é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 un RemoteFunction ne seront pas répliquées à travers la frontière client-serveur, rendant impossible le passage de fonctions à distance. Au lieu de cela, l'argument résultant du 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 d'événement - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Bonjour le monde !")
end
-- Déclencher l'é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 avec des clés numériques et des chaînes. Au lieu de cela, passez une table qui se compose entièrement de 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 d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Table indexée numériquement
local inventoryData = {
"Épée", "Arc"
}
-- Table de dictionnaire
local 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/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. De même, les tables retournées à l'invocateur ne seront pas exactement équivalentes à celles fournies. Vous pouvez démontrer cela en exécutant le script suivant sur un 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 d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Épée", "Arc"
}
-- Afficher l'identité de la table d'origine
print(tostring(inventoryData)) --> table: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Afficher l'identité de la table lors du retour
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Métatables

Si une table a une métatable, toutes les informations de métatable sont perdues lors du transfert. Dans l'exemple de code suivant, la propriété NumWheels fait partie de la métatable 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"] = "MonCamion"}
end
-- Connecter la fonction à l'événement
remoteEvent.OnServerEvent:Connect(onEvent)
Déclenchement d'événement - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "MonCamion"
setmetatable(truck, Car)
-- Déclencher l'événement avec une table incluant une métatable
remoteEvent:FireServer(truck)

Instances non répliquées

Si un RemoteEvent ou un RemoteFunction passe une valeur qui n'est visible que par 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 d'é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 d'événement - LocalScript
local 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èce
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)
©2026 Société Roblox. Roblox, le logo Roblox et Powering Imagination font partie de nos marques déposées aux États-Unis et dans d'autres pays.