My skip stage script doesn't work in-game for some reason apparently?

Recently, I’ve started to work on an obby and everything is going perfectly fine in the studio. Today I’ve published the game (still working in progress) for testing. When I tried to skip a stage, it didn’t teleport me to the stage, but it works in studio with no issue.

These are the scripts I’m using:

ServerScriptService:

local skipId = 1912899950

local mps = game:GetService("MarketplaceService")
local checkpoints = workspace:WaitForChild("Checkpoints")

mps.ProcessReceipt = function(info)
	local plrId = info.PlayerId
	local productId = info.ProductId

	local plr = game.Players:GetPlayerByUserId(plrId)

	if productId == skipId then
		local currentStage = plr.leaderstats.Stage.Value

		local nextStage = currentStage + 1
		local checkpoint = checkpoints:FindFirstChild(tostring(nextStage))

		if checkpoint then
			local character = plr.Character
			if character then
				local targetPosition = checkpoint.Position + Vector3.new(0, 5, 0)
				character:SetPrimaryPartCFrame(CFrame.new(targetPosition))
			end
		end
	end

	return Enum.ProductPurchaseDecision.PurchaseGranted
end

GUI Button:

local skipId = 1912899950

local mps = game:GetService("MarketplaceService")

local maxStage = #game.Workspace.Checkpoints:GetChildren()

script.Parent.MouseButton1Click:Connect(function()
	if game.Players.LocalPlayer.leaderstats.Stage.Value < maxStage then
		mps:PromptProductPurchase(game.Players.LocalPlayer,skipId)
	end
end)

Is there something I’m missing? If so please let me know.

1 Like

You’re not updating the leaderstat. You’re simply overriding the variable you’ve defined its value as but not the actual Instance. Also, please make sure the player actually exists in your server either with a player sanity check or using PlaceIdWherePurchased

3 Likes

Like this?

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local productId = 1912899950

local function onProductPurchased(receiptInfo)
	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then
		warn("Player not found")
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local leaderstats = player:FindFirstChild("leaderstats")
	if not leaderstats then
		warn("Leaderstats not found for ", player.Name)
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local stage = leaderstats:FindFirstChild("Stage")
	if not stage then
		warn("Stage not found for ", player.Name)
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local currentStage = stage.Value
	local nextCheckpoint = workspace.Checkpoints:FindFirstChild(tostring(currentStage + 1))

	if nextCheckpoint then
		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
			player.Character:SetPrimaryPartCFrame(nextCheckpoint.CFrame + Vector3.new(0, 2, 0))
			print("Player", player.Name, "teleported to stage", currentStage + 1)
		else
			warn("Player not found")
		end
	else
		warn("Next checkpoint not found for stage", currentStage + 1)
	end

	return Enum.ProductPurchaseDecision.PurchaseGranted
end

MarketplaceService.ProcessReceipt = onProductPurchased
1 Like

Yeah

1 Like

I’ve published it and tried ingame, still facing the same issue

1 Like

Why are you using tostring?

Just simply make a script that when the player buys it, it ups their stage value by 1 and resets them

1 Like

My main issue here is the developer product not functioning properly, purchase prompt is successful but it doesn’t increase my IntValue or resets my character. Basically nothing happens no matter what script I use.

1 Like

Because the player is nil.

1 Like

Well, what does the output say? Press F9 or navigate the Roblox menu to open the developer console.

Also, make sure you are updating their stage value in the end, also return Enum.ProductPurchaseDecision.NotProcessedYet for the last 2 warnings.

1 Like

Here’s the interesting part. It doesn’t output anything. It’s like the script in ServerScriptService doesn’t exist.

1 Like
  1. Make sure it is actually a Script.
  2. Tell me where is it located.
  3. Make sure no other script is overriding ProcessReceipt callback as that can only be assigned one at a time. You can use the Find All feature to search where else ProcessReceipt occurs.
1 Like

Oh, I see now. It is being overridden by the donation board ModuleScript. Does that mean I have to delete it?

Also yes, it is a script, it is located in ServerScriptService

1 Like

You would have to merge it together. You can simply move your donation board ProcessReceipt into it’s own module function like so:

-- instead of MarketplaceService.ProcessReceipt = function()
function donationModule.ProcessReceipt(info)
    -- your donation board code
end)

And inside your main ProcessReceipt script:

MarketplaceService.ProcessReceipt = function(info)
    if info.ProductId == donationId then
        return donationModule.ProcessReceipt(info)
    elseif info.ProductId == skipId then
        -- your skip code
    end
end
1 Like

Ok I’ve realized something else. ProcessReceipt being overridden was apparently not the issue? My brain that doesn’t probably exist is currently in a meltdown. I found out about it when I deleted the donation board and everything about it.

1 Like

What does your new script look like now along with the new outputs, and can you assure there is no other instances of overriding ProcessReceipt?

You can double confirm if the script is actually running my adding a print statement after hooking your ProcessReceipt function.

1 Like
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local productModule = require(game.ServerScriptService.ProductIds)
local donationModule = require(game.ServerScriptService.DonationModule)

MarketplaceService.ProcessReceipt = function(info)
	if info.ProductId == productModule.DonationProductId then
		return donationModule.ProcessReceipt(info)
	elseif info.ProductId == productModule.SkipProductId then
		local player = Players:GetPlayerByUserId(info.PlayerId)
		if not player then
			warn("Player not found")
			return Enum.ProductPurchaseDecision.NotProcessedYet
		end

		local leaderstats = player:FindFirstChild("leaderstats")
		if not leaderstats then
			warn("Leaderstats not found for ", player.Name)
			return Enum.ProductPurchaseDecision.NotProcessedYet
		end

		local stage = leaderstats:FindFirstChild("Stage")
		if not stage then
			warn("Stage not found for ", player.Name)
			return Enum.ProductPurchaseDecision.NotProcessedYet
		end

		local currentStage = stage.Value
		local nextCheckpoint = workspace.Checkpoints:FindFirstChild(tostring(currentStage + 1))

		if nextCheckpoint then
			local character = player.Character
			if character and character:FindFirstChild("HumanoidRootPart") then
				local targetPosition = nextCheckpoint.Position + Vector3.new(0, 5, 0)
				character:SetPrimaryPartCFrame(CFrame.new(targetPosition))
				print("Player", player.Name, "teleported to stage", currentStage + 1)
			else
				warn("Character or HumanoidRootPart not found for ", player.Name)
			end
		else
			warn("Next checkpoint not found for stage", currentStage + 1)
		end

		return Enum.ProductPurchaseDecision.PurchaseGranted
	end
end

by the way that just fully killed the script (this is getting way too advanced for me now)

1 Like

Outputs? Assure your code is running by adding a simple print statement after your ProcessReceipt. Are you sure your donation module is not yielding infinitely?

1 Like

I’ve mentioned that I’ve fully removed the donation board and “everything” about it.

1 Like

Then why keep the donation part in your script?

1 Like

Add a print to this line like this:

if info.ProductId == productModule.DonationProductId then
Print(“ProcessReceipt)
		return donationModule.ProcessReceipt(info)

And it prints “ProcessReceipt” then that could be your problem

1 Like