Asynchronous calls always need to be wrapped in pcall. They can fail for connectivity issues or the service being down. You need to be able to handle these spontaneous errors.
Note taken, thanks!
Iâve been having this exact issue sparadically and it sounds unreal to me. My game reaches very high traffic so itâs a hotbed for this issue and Iâve been dealing with lots of complaints. I canât find any pattern why this happens so Iâm assuming itâs random? By chance, are you still dealing with this issue?
Exclusively on weekends for me. Itâs incredibly annoying.
Iâd say 1 out of 500 purchases have this happen as an educated guess
Now this error message should contain invalid data which might explain why it fails. Could you please send it to me if you meet one? Thanks.
Load passes fail:MarketPlace::UserOwnsGamePassAsync: Parsed invalid JSON: ï»ż{"errors":[{"code":0,"message":"Something went wrong with the request, see response status code."}
Load passes fail:MarketPlace::UserOwnsGamePassAsync: failed due to empty response
So Iâm pretty heated now.
Can we talk about how in these release notes just released here: Documentation - Roblox Creator Hub
It says this:
The result of MarketplaceService:UserOwnsGamePassAsync will now be cached.
This was the one thing that EVERYONE was complaining about and was asking about when this new service was released. Why is it now going to cache again? This is a huge pain point because we have to implement a separate check every time we sell something in-game again if they bought it in the game. Also, if they buy it from the store page while in-game, we have no way to know that they now have the gamepass unless they rejoin the server!
Am I misunderstanding something? Why this change when we were assured this new service wouldnât cache (and it didnât up until now)?
My original post was slightly inaccurate, and I apologize for any confusion.
I have investigated further into how it works, and here is what Iâve currently observed:
- If the user owns the gamepass upon the initial check, it will remain
true
for the full game session. - If the user does not own the gamepass, it will cache that
false
result for about 10 seconds before allowing a live result to be returned again.
So yes, there is now a slight discrepancy, but whatâs important to note here is that it wonât stay false if you call it when the user doesnât own the gamepass. If you check again shortly after, it will give you a live result again.
What happens if the user buys the gamepass in-game within that 10 seconds? Will the cached value for that gamepass be cleared?
You would use PromptGamePassPurchaseFinished/etc to detect when the player purchases a gamepass in-game â not constantly polling UserOwnsGamePassAsync.
Seems this is more relevant to purchasing gamepasses outside the game (store page), and I doubt that would clear the cache. Roblox would constantly have to poll the webserver to check if the player bought the pass to know when to invalidate the cache, defeating the purpose of caching the value for 10 seconds.
I understand that it makes sense to use PromptGamePassPurchaseFinished
to give gamepass rewards ASAP, but in some cases UserOwnsGamePassAsync
is checked on button press, on touch, or through event-triggered scenarios. Just because UserOwnsGamePassAsync
is run after a gamepass is purchased in-game does not mean that itâs being polled constantly.
In these cases it would be nice for Roblox to automatically clear the cache for a bought gamepass when itâs purchased in-game. There is no reason to have to wait 10 seconds for the cache to update when the Roblox server has already knows that the cache is no longer valid.
If Roblox doesnât implement this, then the only way to have event-triggered passes work within that 10 second window is if we write our own cache on top of Robloxâs cache that updates when users purchase passes. This should not be necessary. The Roblox gamepass system and its caching mechanism should be good enough to support this use case.
Some examples of event-triggered passes:
- A door that only lets you through if you own a gamepass
- A button that teleports you. If you own the gamepass, you teleport. If you donât own the gamepass, it prompts you to purchase it.
- Special abilities for gamepass owners in a round-based game, which is checked only at the start of the round.
I could list other examples, but I donât think I need to. In all three of these examples, having to wait 10 seconds after purchasing a gamepass is an annoyance. This is an even greater annoyance in the round-based game scenario, since users will have to wait the whole round to use their gamepass.
This issue can be worked around, but we shouldnât have to work around it. Roblox already has a cache. We shouldnât have to write our own with a small bit of extra behavior just because Robloxâs isnât good enough. If Roblox is aiming to make checking and handling gamepasses easy for developers and responsive for players, then for event-triggered scenarios we need the gamepass cache to clear for passes that are bought in-game.
What I personally do is set a module with a UserOwnsGamepass
function. This module has an internal purchase cache of all gamepass purchases made in that particular server and will check against this cache before calling UserOwnsGamePassAsync
.
Do not necrobump old announcements