Module 07 · Leçon 2 sur 6
Les Game Passes
Crée un Game Pass dans le Creator Hub, vérifie qui le possède avec UserOwnsGamePassAsync et propose l’achat en jeu pour offrir une traînée dorée exclusive.
- ⏱️ 35 min
- 📝 Quiz de 6 questions
- 🔄 Vérifié le 24 octobre 2026
Sur cette page
- Game Pass ou Developer Product ?
- Créer le Game Pass dans le Creator Hub
- Récupérer l’identifiant du pass
- Les trois fonctions à connaître
- Le script serveur : vérifier et donner l’avantage
- Le bouton de la boutique : proposer l’achat
- Mise en cache : ne pas interroger Roblox en boucle
- Tester ton Game Pass
- Quiz de fin de leçon
🎯 Dans cette leçon, tu vas apprendre à…
- Créer un Game Pass et récupérer son identifiant
- Vérifier côté serveur qu’un joueur possède un pass, avec pcall
- Proposer l’achat en jeu et réagir à la fin de l’achat
- Appliquer et mémoriser l’avantage du pass de façon fiable
Dans la leçon précédente, tu as vu que l’Obby des Nuages vendrait une traînée dorée exclusive. C’est l’exemple parfait de Game Pass : un achat unique, un avantage permanent, purement cosmétique. Dans cette leçon, tu vas le créer, puis écrire le code qui le vend et le donne, sans jamais faire confiance au client (souviens-toi du module 4).
Game Pass ou Developer Product ?
Roblox propose deux grands types d’objets payants en jeu. Le choix est simple :
- Game Pass (appelé « pass » dans le Creator Hub) : le joueur paie une seule fois et garde l’avantage pour toujours. Exemples : accès à une zone VIP, un objet d’avatar en jeu, un bonus permanent, notre traînée dorée.
- Developer Product : le joueur peut l’acheter autant de fois qu’il veut. Exemples : monnaie, potions, « passer l’étape ». On le verra à la leçon 3.
Un bon réflexe : si la phrase « je l’achète une fois et c’est à moi » décrit l’objet, c’est un Game Pass.
Créer le Game Pass dans le Creator Hub
Ton jeu doit d’abord être publié et accessible sur Roblox (tu l’as fait au module 1). Ensuite, d’après la documentation officielle :
- Va dans Creations et sélectionne ton Obby des Nuages.
- Ouvre Monetization puis Passes.
- Clique sur Create pass.
- Ajoute une icône : 512 × 512 pixels maximum, au format
.jpg,.pngou.bmp. L’icône est découpée en cercle, donc garde l’important au centre. - Donne un nom et une description honnête (« Une traînée dorée suit ton personnage. Purement cosmétique. »).
- Choisis une catégorie (elle sert à ranger les objets dans la boutique en jeu).
- Clique sur Create pass.
Il te reste à fixer le prix et à mettre le pass en vente depuis la page du pass dans le Creator Hub. La documentation officielle ne détaille plus cette étape (octobre 2026) ; elle mentionne seulement une page Sales du pass, qui affiche notamment ses prix par pays. Les écrans du Creator Hub évoluent souvent : si un libellé a changé, cherche l’option de prix et de mise en vente dans la page du pass.
Récupérer l’identifiant du pass
Pour le script, tu as besoin de l’ID du pass : dans Monetization › Passes, survole la vignette du pass, clique sur le bouton ⋯ puis sur Copy Asset ID. Garde ce nombre de côté.
Les trois fonctions à connaître
Tout passe par le service MarketplaceService (le service des achats en jeu).
| Fonction ou événement | Rôle |
|---|---|
MarketplaceService:UserOwnsGamePassAsync(userId, gamePassId) |
Renvoie true si le joueur possède le pass. Fonction qui attend une réponse réseau : toujours dans un pcall. |
MarketplaceService:PromptGamePassPurchase(player, gamePassId) |
Affiche la fenêtre d’achat officielle de Roblox au joueur. |
MarketplaceService.PromptGamePassPurchaseFinished |
Événement déclenché quand cette fenêtre se ferme. Il reçoit (player, gamePassId, wasPurchased). |
Deux détails de la documentation officielle à retenir :
UserOwnsGamePassAsyncattend l’UserId du joueur (un nombre), pas l’objetPlayer.PromptGamePassPurchaseFinishedse déclenche aussi quand le joueur annule. Le troisième paramètre,wasPurchased, vauttrueseulement si l’achat a réussi. Et cet événement doit être écouté côté serveur : côté client, ses valeurs ne doivent pas servir à valider quoi que ce soit.
Le script serveur : vérifier et donner l’avantage
Voici le cœur du système. Il fait trois choses :
- quand un joueur arrive, il vérifie s’il possède déjà le pass ;
- quand un joueur termine un achat réussi, il lui donne l’avantage tout de suite ;
- à chaque réapparition du personnage, il remet la traînée.
L’avantage est mémorisé dans un attribut du joueur (PossedeTrailDore), que les autres scripts (et l’interface) peuvent lire. Dans ton projet Rojo, ce Script est le fichier src/ServerScriptService/GamePassTrail.server.luau. Tu peux le faire écrire par Claude Code avec le prompt de l’encadré « Avec Claude Code » (après la section sur le bouton), mais un code d’achat se relit toujours : les explications ci-dessous sont ta grille de lecture.
-- Script (côté serveur) à placer dans ServerScriptService, nommé « GamePassTrail »
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local ID_PASS_TRAIL_DORE = 0 -- remplace 0 par l'ID de TON pass (Copy Asset ID)
-- Ajoute une traînée dorée au personnage (si elle n'y est pas déjà)
local function ajouterTrail(character: Model)
local rootPart = character:WaitForChild("HumanoidRootPart", 5)
if rootPart == nil or rootPart:FindFirstChild("TrailDore") then
return
end
-- Une traînée a besoin de deux points d'attache (Attachments)
local haut = Instance.new("Attachment")
haut.Name = "TrailHaut"
haut.Position = Vector3.new(0, 1, 0)
haut.Parent = rootPart
local bas = Instance.new("Attachment")
bas.Name = "TrailBas"
bas.Position = Vector3.new(0, -1, 0)
bas.Parent = rootPart
local trail = Instance.new("Trail")
trail.Name = "TrailDore"
trail.Attachment0 = haut
trail.Attachment1 = bas
trail.Color = ColorSequence.new(Color3.fromRGB(255, 210, 80))
trail.Lifetime = 0.6
trail.Parent = rootPart
end
-- Donne l'avantage : on le note dans un attribut, puis on l'applique
local function accorderPass(player: Player)
player:SetAttribute("PossedeTrailDore", true)
if player.Character then
ajouterTrail(player.Character)
end
end
-- Vérifie la possession du pass, avec quelques nouvelles tentatives
local function verifierPass(player: Player)
for tentative = 1, 3 do
local ok, resultat = pcall(function()
return MarketplaceService:UserOwnsGamePassAsync(player.UserId, ID_PASS_TRAIL_DORE)
end)
if ok then
if resultat == true then
accorderPass(player)
end
return
end
warn("Vérification du pass impossible (essai " .. tentative .. ") : " .. tostring(resultat))
task.wait(2)
end
end
local function onPlayerAdded(player: Player)
-- À chaque réapparition, on remet la traînée si le joueur a le pass
player.CharacterAdded:Connect(function(character)
if player:GetAttribute("PossedeTrailDore") then
ajouterTrail(character)
end
end)
verifierPass(player)
end
Players.PlayerAdded:Connect(onPlayerAdded)
-- Joueurs déjà présents si le script démarre en retard
for _, player in Players:GetPlayers() do
task.spawn(onPlayerAdded, player)
end
-- Achat terminé : on ne donne l'avantage que si l'achat a RÉUSSI
MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player, idPass, achete)
if achete and idPass == ID_PASS_TRAIL_DORE then
accorderPass(player)
end
end)
Prends le temps de relire les points clés :
pcallentoureUserOwnsGamePassAsync: si Roblox ne répond pas, le script ne plante pas et réessaie deux fois.- On compare
idPassà notre ID : si tu vends plusieurs passes, chacun doit avoir son propre traitement. - L’avantage est appliqué par le serveur. Un exploiteur peut modifier son propre client, pas l’attribut décidé par le serveur.
Le bouton de la boutique : proposer l’achat
Côté client, on affiche le vrai prix et on ouvre la fenêtre d’achat quand le joueur clique. Dans la boutique du module 5, crée un TextButton nommé BoutonTrailDore dans InterfaceObby › Boutique › Liste (le UIGridLayout le range avec les traînées), puis crée dedans un LocalScript nommé ScriptBouton avec ce code. Dans le script serveur et dans celui-ci, remplace 0 par l’ID de ton pass.
-- LocalScript placé dans le TextButton « BoutonTrailDore »
-- (StarterGui > InterfaceObby > Boutique > Liste > BoutonTrailDore)
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local ID_PASS_TRAIL_DORE = 0 -- le même ID que dans le script serveur
local joueur = Players.LocalPlayer
local bouton = script.Parent :: TextButton
-- Affiche le prix réel : il peut varier selon le pays ou une réduction
local ok, infos = pcall(function()
return MarketplaceService:GetProductInfoAsync(ID_PASS_TRAIL_DORE, Enum.InfoType.GamePass)
end)
if ok and infos.PriceInRobux then
bouton.Text = "Traînée dorée : " .. infos.PriceInRobux .. " Robux"
end
-- Si le joueur possède déjà le pass, on l'indique sur le bouton
local function mettreAJourBouton()
if joueur:GetAttribute("PossedeTrailDore") then
bouton.Text = "Traînée dorée : possédée"
end
end
bouton.Activated:Connect(function()
if joueur:GetAttribute("PossedeTrailDore") then
return -- inutile de proposer un pass déjà possédé
end
MarketplaceService:PromptGamePassPurchase(joueur, ID_PASS_TRAIL_DORE)
end)
joueur:GetAttributeChangedSignal("PossedeTrailDore"):Connect(mettreAJourBouton)
mettreAJourBouton()
Ici, le client demande l’achat, mais c’est Roblox qui affiche la fenêtre et encaisse les Robux, puis notre script serveur qui donne la traînée. Le client ne peut rien s’attribuer lui-même.
Mise en cache : ne pas interroger Roblox en boucle
UserOwnsGamePassAsync est déjà mis en cache par Roblox : selon la documentation, les appels répétés répondent plus vite, et le cache est mis à jour quand PromptGamePassPurchaseFinished se déclenche. Un joueur qui rejoint un serveur après avoir acheté le pass est toujours reconnu comme propriétaire.
Notre script ajoute sa propre « mémoire » : l’attribut PossedeTrailDore. Résultat :
- un seul appel réseau par joueur à son arrivée ;
- tous les autres scripts (boutique, inventaire du module 5) lisent simplement l’attribut, sans attendre.
Tester ton Game Pass
Tester l’achat d’un pass demande un peu de méthode, car Studio ne simule pas vraiment l’achat de passes. La page officielle du kit « Season Passes » (documentation Roblox, consultée en octobre 2026) le dit clairement : pour tester l’achat d’un pass, il faut publier le jeu et tester dans le client Roblox. Une ancienne annonce du staff Roblox (DevForum, 2016) précisait déjà qu’aucun Robux n’est débité pour un achat fait dans Studio, mais que la vérification de possession d’un pass pouvait y renvoyer une valeur incorrecte.
Procède donc en deux temps :
- Dans Studio (Play) : vérifie que le bouton affiche le prix et ouvre la fenêtre d’achat, et que rien ne se passe si tu cliques sur Annuler. Pour tester l’effet lui-même, ajoute temporairement
accorderPass(player)au début deonPlayerAdded: la traînée doit apparaître, revenir après une mort (réapparition), et le bouton doit afficher « possédée ». Retire cette ligne avant de publier ! - Dans le jeu publié : rejoins le jeu avec un compte qui possède réellement le pass pour tester la vérification à l’arrivée (
UserOwnsGamePassAsync), et, si tu veux testerPromptGamePassPurchaseFinisheden conditions réelles, fais un véritable achat (il coûte de vrais Robux : si tu es mineur, demande d’abord l’accord d’un parent). Ce dernier test est facultatif : personne n’est obligé de dépenser des Robux pour suivre cette leçon.
Ce qu’il faut retenir
- Un Game Pass est un achat unique pour un avantage permanent ; on le crée dans Monetization › Passes et on copie son ID avec Copy Asset ID.
UserOwnsGamePassAsync(userId, gamePassId)vérifie la possession : toujours dans unpcall, côté serveur, à l’arrivée du joueur.PromptGamePassPurchase(player, gamePassId)ouvre la fenêtre d’achat ;PromptGamePassPurchaseFinishedse déclenche même en cas d’annulation : vérifiewasPurchased.- L’avantage est appliqué par le serveur et mémorisé (attribut), puis réappliqué à chaque réapparition.
- Le prix affiché se lit avec
GetProductInfoAsync, car il peut varier selon le joueur.
Sources et pour aller plus loin
- Passes — guide officiel (création, ID, vente, attribution)
- MarketplaceService — référence de l’API
- Regional pricing — prix régionaux et Managed Pricing
- Roblox Plus — avertissement sur les prix écrits en dur
- Season Passes — « Studio does not mock pass purchasing » (documentation Roblox)
- Mock purchases in Studio — annonce du staff Roblox sur le DevForum (2016, ancienne)