So I have this game which is similar to logo quiz/guess the picture games, where you need to guess the picture by typing the answer in the chat for the door to open (cancollide = false) and you pass through to the next quiz door. Now I don’t have checkpoint systems or a leaderstats because each category has its own area, but I want to make it so that the quiz door has a proximity prompt where if you click it, it shows the purchase prompt to buy the developer product “skip stage” and if you do buy it, then the door will open (cancollide = false) for a certain period of time then will close (cancollide = true) to its normal state. I also want to make it work so that even if you skip the stage, everyone else in the server will see that the door has opened and they can also go through to the next stage. How do I make such a thing?
you have to make a script when you buy it it teleports you to the next stage so if your at a certain stage when you buy it it takes you to the stage infront of you
That’s the thing, I don’t want it to teleport you because I don’t have (or intend to use) stages or leaderstats, I just want to make it so that when you purchase the developer product the door will become uncancollide for everyone on the server for a certain amount of seconds then it will go back to being cancollide = true
so you have to make it to where if the marketplace service was bought it would add 1 to the stages
then reset the character after you buy it and it adds the stage
Not exactly what I meant, the door has a proximity prompt and when the player clicks it, it will show the purchase developer product prompt, and if the purchase was successful, then the door will become uncancollide for everyone in the server so that they can pass through it to the next quiz door, there are no checkpoints or stages in the game.
door.cancollide = true workspace[‘FIlteringEnabled’] = false
you have to use these in a script
or +1 door then make the door infront of the player uncollideable
You can PromptProductPurchase on the client or the server, it doesn’t matter because the receipt and the purchase will be handled on the server.
use GetService to retrieve MarketplaceService and set the .ProcessReceipt callback to your own function on the server.
It returns a dictionary containing data such as a user’s ID and the product ID they purchased.
You should use basic logic to make sure the purchase has gone through, it’s not a duplicate so on and so forth.
You can read up on the example code and whatnot provided on the documentation here
To answer your question broadly, you’d check when the proximity prompt is triggered, prompt the product purchase to that user. Meanwhile, marketplace service is listening for when that product is purchased, and when it is, you make the door cancollide and whatever else you want to do, this should be on the server to ensure that it happens for all players like you wished.
smart i couldnt think of that but the user id is good because if you use username they could change their username and when they play the game again they would lose their progress so its better to use userid always
I’m not a very good scripter so apologies in advance for the script & the questions.
So I tried messing around and this is what I came up with so far but it doesn’t seem to do anything & gives no errors in output, would you mind helping me figure it out?
The local script inside the quiz door part:
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local productId = 1324198149 -- Change this to your developer product ID
-- Function to prompt purchase of the developer product
script.Parent.ProximityPrompt.Triggered:Connect(function()
local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService:PromptProductPurchase(player, productId)
end)
MarketplaceService.ProcessReceipt = function(receiptInfo)
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if receiptInfo.ProductId == 1324198149 then
script.Parent.CanCollide = false
workspace.SkipStageSound:Play()
wait(7)
script.Parent.CanCollide = false
workspace.SkipStageSound:Stop()
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
The quiz door in workspace:
Local scripts don’t run in the workspace, place it in starter player scripts and change the variables to make them work.
Put this part in a server script (preferably in ServerScriptService)
Thank you! I have made the server script and placed it into ServerScriptService and edited the script a little bit which looks like this now:
Server Script:
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local Players = game:GetService("Players")
local player = Players.PlayerAdded:Wait()
local productId = 1324198149 -- Change this to your developer product ID
-- Function to prompt purchase of the developer product
workspace.doord.ProximityPrompt.Triggered:Connect(function()
local MarketplaceService = game:GetService("MarketplaceService")
MarketplaceService:PromptProductPurchase(player, productId)
end)
MarketplaceService.ProcessReceipt = function(receiptInfo)
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
if receiptInfo.ProductId == 1324198149 then
workspace.doord.CanCollide = false
workspace.SkipStageSound:Play()
wait(7)
workspace.doord.CanCollide = false
workspace.SkipStageSound:Stop()
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
I also added a Local Script inside the quiz door part that is found in workspace:
script.Parent.ProximityPrompt.Triggered:Connect(function()
local marketPlaceService = game:GetService("MarketplaceService")
marketPlaceService:PromptProductPurchase(game.Players.LocalPlayer, 1324198149)
end)
Everything is working fine but for some reason after the door becomes uncancollide it stays like that forever instead of going back to cancollide = true after a specific amount of seconds, how do I fix that issue?
Below the wait, you’re supposed to change the door back to true. Common mistake, we’ve all been there.
Oh god, I didn’t notice that for some reason. Thank you so much!!!
one last question, I should’ve done this earlier buuuut its kinda too late and I have over 200-300 quiz doors in the game, all of them are named “door” and so I wanted at first to just copy and paste the script to all the doors/parts and that’s it but I’m not sure how would I make it so that it only opens the door the player is at and not all the other doors without having to change the name of each door? Or is it not possible to do so?
It’s either you make an IntValue that correlates to what door number it is, or you name the doors to that door number. There’s really no way around that, unless you have the script automatically number the doors (but not recommended since, it’ll just take the doors as a table and the order may or may not be right. because they’re the same named instance).
For the script, so that you don’t have to pain your fingers 4x more putting it in the code, can simply take the value (or the name of the door, and only taking the numbers) and apply it to that door specifically.
I’ll code two ways of doing it within the LocalScript:
-- LocalScript
-- Since we'll have to send the data of which door the player opened we have to send the data from the player to the server.
-- And because we're using a local script for the trigger, we'll need to send the door number to the server via RemoteEvent.
-- Which means, we'll need to make a remote in the server.
-- So for now, we'll have it so this script will find or wait for the remotes folder and finds the remote that it's looking for.
-- We'll make the folder and remote in the script, OR you can make it yourself within the game.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local RemoteFolder = ReplicatedStorage:WaitForChild("Remotes")
local DoorRemote = RemoteFolder:WaitForChild("DoorRemote")
local door = script.Parent.Parent -- assuming the prompt is parented to the door itself
local doorNum
-- So we could either get the door's number from it's name:
doorNum = tonumber(door:sub(5)) -- this will skip the "door" part of the name (it's 5 because even no character is a character)
-- Or, we could make an IntValue with the number there:
doorNum = door:FindFirstChildOfClass("IntValue").Value
script.Parent.ProximityPrompt.Triggered:Connect(function()
local marketPlaceService = game:GetService("MarketplaceService")
marketPlaceService:PromptProductPurchase(game.Players.LocalPlayer, 1324198149)
RunService.Heartbeat:Wait()
DoorRemote:FireServer(doorNum)
end)
-- ServerScript
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- local Players = game:GetService("Players") duplicate line, remove it
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--[[
local RemoteFolder = Instance.new("Folder") -- remember the folder we was going to make?
RemoteFolder.Name = "Remotes"
RemoteFolder.Parent = ReplicatedStorage
local DoorRemote = Instance.new("RemoteEvent")
DoorRemote.Name = "DoorRemote"
DoorRemote.Parent = RemoteFolder
]] -- Again, this is optional if you're going to just make it yourself.
-- If you are, you'd instead do this:
local RemoteFolder = ReplicatedStorage.RemoteEvent
local DoorRemote = RemoteFolder:WaitForChild("DoorRemote")
local player = Players.PlayerAdded:Wait()
local productId = 1324198149
MarketplaceService.ProcessReceipt = function(receiptInfo)
local player = game.Players:GetPlayerByUserId(receiptInfo.PlayerId)
local doorNum = DoorRemote.OnServerEvent:Wait() -- you could do this...
if receiptInfo.ProductId == 1324198149 then
workspace["door" .. doorNum].CanCollide = false
workspace.SkipStageSound:Play()
wait(7)
workspace["door" .. doorNum].CanCollide = false
workspace.SkipStageSound:Stop()
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
This may or may not work, I’m not entirely sure. Let me know how the scripts perform for you.