It could be because the playerAdded function hasn’t been called on the current players, and the script is somehow delayed? I added some print statements into my code and initialized the players at the bottom. In the output, see if you can catch “YEET” or “NAH”, which determines whether the gamepass is owned.
-- Services and Variables
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")
local GAMEPASS_ID = 19711172
-- A cache to index if a player owns the gamepass when they join
local cache = {}
local function playerAdded(player)
player.CharacterAdded:Connect(function(character)
-- Repeats until ownership is detected
if cache[player] == nil then
repeat
wait()
until
cache[player] ~= nil
end
-- If the player owns the gamepass, clone the gravity coil into their backpack
local ownsGamepasses = cache[player]
if ownsGamepasses then
print("YEET")
ServerStorage.GravityCoil:Clone().Parent = player:WaitForChild("Backpack")
else
print("NAH")
end
end)
-- This runs ONLY ONCE because UserOwnsGamePassAsync is an expensive function
-- IT shouldn't be called every time the player spawns, so ownership will be indexed in the cache
local success, hasPass = pcall(function()
return MarketplaceService:UserOwnsGamePassAsync(player.UserId, GAMEPASS_ID)
end)
if success then
cache[player] = hasPass
else
warn("Failed to retrieve ownership data: " .. player.Name)
cache[player] = false
end
end
-- Initialize Players
for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(playerAdded)(player)
end
Players.PlayerAdded:Connect(playerAdded)
If you see “YEET” and the tool still isn’t in the backpack, then something is wrong with the cloning. BUT, if you see “NAH”, then you don’t own the gamepass!
Let me know if you have any questions, I’m going to head off for now but I’ll check in
The result is only cached on the server (at least what it seem, based on that other functions that have this behaviour) however therefore calls on the client are expensive.
Ah yes, i was just on that page haha! I remember now why I had a custom caching system, it was because of the PromptGamePassPurchase and the Finished event, since the caching system of this async doesn’t handle that. But since this code doesn’t handle in-game purchases and receiving the tools in real-time, using the async on each spawn should be durable
It’s interesting why the default Roblox system doesn’t account for this, it seems like something that should have been included especially the fact that PlayerOwnsAsset doesn’t have caching behaviour. Am I the only one that wants consistency in these functions?
FOR REAL, I really hope they make this a feature soon. I might as well create an open-sourced module that handles the caching for easy use of other developers
-- Services and Variables
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local ServerStorage = game:GetService("ServerStorage")
-- PassName and ID
local passes = {
GravityCoil = 19711172,
-- ADD MORE HERE IF YOU WANT
}
local function playerAdded(player)
-- Function that returns true or false, depending on ownership of pass
local function ownsPass(name)
return MarketplaceService:UserOwnsGamePassAsync(player.UserId, passes[name])
end
player.CharacterAdded:Connect(function(character)
-- Check if player owns "GravityCoil"
if ownsPass("GravityCoil") then
ServerStorage.GravityCoil:Clone().Parent = player:WaitForChild("Backpack")
end
end)
end
-- Initialize Players
for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(playerAdded)(player)
end
Players.PlayerAdded:Connect(playerAdded)
I created a passes table where you can index the pass name and the ID. There’s a function that checks whether or not the player owns the pass, “ownsPass.” You add add more gamepasses into the table if needed and create your own events
Your code logical wise seems fine, so what I am thinking is that either there’s no tool in ServerStorage named “GravityCoil” which causes the code to crash, or if there is an object named so, perhaps its not a Tool object? or maybe the code is running before everything in ServerStorage is loaded?
so to be sure, I recommend that you open the output panel by going view -> output and see if there’s any errors