how do you put text on your gamepass so when it is purchased it will say owned then they can’t purchase it anymore?
Are you wanting to do this on a UI or what are you wanting to do this on?
I suggest you look at the PromptGamePassPurchasedFinished event to change your UI when someone has purchased a gamepass.
This can be done, but this would be inefficient since you’d have to create a datastore to save owned gamepasses (with a chance of roblox going down) or this only happening for one time. Here’s the more efficient way to do it: UserOwnsGamePassAsync
Using UserOwnsGamePassAsync, you can do a check like this in a server script and a remote function:
local plrs = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local returnpassowned = RS:WaitForChild("ReturnPassOwned")
local MS = game:GetService("MarketplaceService")
local passId = 0 -- Put your gamepass here
plrs.PlayerAdded:Connect(function(plr)
while task.wait(5) do
if MS:UserOwnsGamePassAsync(plr.UserId, passId) then
returnpassowned:InvokeClient(plr, passId)
--[[ Any additional benefits you wanna give the player, this is not prone to exploiters since
its done on the serverside and checking only if the player owns the gamepass,
not if it was fired by a remote or etcetera. ]]
end
end
end)
Here’d be the localscript side, which changes the text to “Owned”
local RS = game:GetService("ReplicatedStorage")
local returnPassOwned = RS:WaitForChild("ReturnPassOwned")
local passIdFromBefore = 0 -- the passID from before
returnPassOwned.OnClientInvoke = function(passId)
if passId == passIdFromBefore then
script.Parent.Text = "Owned"
end
end
ok thanks guys ill need a little help with the datastore tho
No, you don’t need to do a datastore. It’s inefficient as I said. I gave you some better script examples. But if you want to, here: Data Stores | Roblox Creator Documentation
You don’t need the Remote Function and you also don’t need datastores. You can check everytime the player joins the game. (as you already said)
I wrote a small example with the UI.
local MS = game:GetService("MarketplaceService")
local ownedTXT = script.Parent.OWND
local plr = game.Players.LocalPlayer
local GamePassID = 0 -- Your gamepass id here
game.Loaded:Connect(function()
if MS:UserOwnsGamePassAsync(plr.UserId, GamePassID) == true then
ownedTXT.Text = "Owned"
else
ownedTXT.Text = "Not Owned"
end
end)
The text will say “owned” if you own it. If not, it will say “not owned”.
Ok, I gave some more examples for the DataStore if you still wanna use it (but it’s not recommended) - Here’s the server sided script:
local MSS = game:GetService("MarketplaceService")
local DSS = game:GetService("DataStoreService")
local PDS = DSS:GetDataStore("Gamepasses")
local RS = game:GetService("ReplicatedStorage")
local returnpassowned = RS.ReturnPassOwned
local pass1 = 0 -- Pass ID
MSS.PromptGamePassPurchaseFinished:Connect(function(plr, passId, success)
if success then
if passId == pass1 then
local s, r = pcall(function() -- Here's where the danger comes in, there's a chance of the datastore failing
local info = PDS:GetAsync(plr.UserId)
if info and typeof(info) == "table" then
local newInfo = info
table.insert(newInfo, pass1)
PDS:SetAsync(plr.UserId, newInfo)
else
PDS:SetAsync(plr.UserId, {pass1})
end
end)
if not s and r then
warn(r)
end
returnpassowned:InvokeClient(plr, passId)
-- Any other benefits
end
end
end)
And here would be the localscript from before, under the GUI text:
local RS = game:GetService("ReplicatedStorage")
local returnPassOwned = RS:WaitForChild("ReturnPassOwned")
local passIdFromBefore = 0 -- the passID from before
returnPassOwned.OnClientInvoke = function(passId)
if passId == passIdFromBefore then
script.Parent.Text = "Owned"
end
end
The RemoteFunction actually is needed this time because the server saves to DataStoreService. Sorry about the last scripts I posted.
Oops. I realised that RemoteEvents are more fitting to be used than RemoteFunctions.
You can change this line in the server script:
returnpassowned:InvokeClient(plr, passId)
To:
returnpassowned:FireClient(plr, passId)
And the localscript to this
local RS = game:GetService("ReplicatedStorage")
local returnPassOwned = RS:WaitForChild("ReturnPassOwned")
local passIdFromBefore = 0 -- the passID from before
returnPassOwned.OnClientEvent:Connect(function(passId)
if passId == passIdFromBefore then
script.Parent.Text = "Owned"
end
end)
And then make a RemoteEvent in ReplicatedStorage and rename it to ReturnPassOwned and delete the RemoteFunction
the script now: local MS = game:GetService(“MarketplaceService”)
local ownedTXT = script.Parent.OWND
local plr = game.Players.LocalPlayer
local GamePassID = 38706262
script.Parent.MouseButton1Click:Connect(function()
game:GetService(“MarketplaceService”):PromptGamePassPurchase(game.Players.LocalPlayer, 38706262)
script.Parent.Text = “REJOIN TO GET YOUR GEAR!!”
wait(1)
game.Loaded:Connect(function()
if MS:UserOwnsGamePassAsync(plr.UserId, GamePassID) == true then
ownedTXT.Text = “Owned”
else
ownedTXT.Text = “Not Owned”
end
end)
end)
it works but the text doesnt change
Change this
game.Loaded:Connect(function()
if MS:UserOwnsGamePassAsync(plr.UserId, GamePassID) == true then
ownedTXT.Text = “Owned”
else
ownedTXT.Text = “Not Owned”
end
end)
end)
to
while task.wait(1) do
if MS:UserOwnsGamePassAsync(plr.UserId, GamePassID) == true then
ownedTXT.Text = “Owned”
else
ownedTXT.Text = “Not Owned”
end
end
Apologies, I must not have been clear enough. I was just saying to use that when someone had purchased a gamepass and had not gone into any more detail. I was not going to suggest the use of a datastore and did not mention initially checking if they own it upon joining. Thank you for expanding upon what I had said.
It appears there is an error with this: local ownedTXT = script.Parent.OWND
That is not the best of ideas. I believe that UserOwnsGamePassAsync caches data like how player:GetRankInGroup() and other things. You should just be using the event to detect when they have purchased it instead.
My bad, check the new script that I edited - I accidentally added another end
No, why would UserOwnsGamePassAsync cache GetRankInGroup? I’ve used the same method they’re using and it works perfectly so I don’t get what the point is.
The best solution is to get the information about the gamepass when joining via UserOwnsGamePassAsync - setting text to “OWNED” if bought and “NOT OWNED” if not. Later on, you can update the text if the user buys the gamepass.
The only situation in which this may not work is if the user DELETES the gamepass whilst playing, but this shouldn’t be an issue.
thanks, but would you need a bracket at the end of the last end?
No, because the while loop doesn’t have an open parentheses.