Issues with checkpoint and skip stage script

Hi,

I have a checkpoint and a skip stage script in my ServerScriptService and sometimes the skip stage script doesn’t work. Some parts of the script are now highlighted and I have no idea what the issue is.

Here is the skip stage script for ServerScriptService:

MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService.ProcessReceipt = function(receiptInfo)
	player = game.Players:GetPlayers()

	currency = "Stage"

	done = 0

	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId then
			if receiptInfo.ProductId == 16231369024 and done == 0 then
				done = 1
				players[i].leaderstats[currency].Value = players[i].leaderstats[currency].Value + 1
				players[i].Character.Humanoid.Health = 0
				done = 0
			end
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted	
end

The server side checkpoint script works but it displays 2 error messages, one every time a player touches it and the other one when a player joins the game. The error message that displays when a player touches the checkpoint is:

ServerScriptService.CheckpointScript:23: attempt to perform arithmetic (sub) on string and number

I searched it up and it has something to do with defining Amount.

And here is the error message that pops up in output when a player joins the game.

ServerScriptService.CheckpointScript:37: attempt to index nil with ‘CFrame’

Here is also my server side checkpoint script that I am using:

local Rs = game.ReplicatedStorage
local Event = Rs:WaitForChild("Events")

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Parent = Player
	leaderstats.Name = "leaderstats"
	
	local Stage = Instance.new("NumberValue")
	Stage.Parent = leaderstats
	Stage.Name = "Stage"
	Stage.Value = 0
	
	local CheckpointsFolder = game.Workspace:FindFirstChild("Checkpoints")
	
	for i, Checkpoint in pairs(CheckpointsFolder:GetChildren()) do
		
		Checkpoint.Touched:Connect(function(Hit)
			if Hit.Parent:FindFirstChild("Humanoid") then
				local PlayerHit = game.Players:GetPlayerFromCharacter(Hit.Parent)
				
				
				if PlayerHit.leaderstats:FindFirstChild("Stage").Value == Checkpoint.Name - 1 then
					PlayerHit.leaderstats:FindFirstChild("Stage").Value = Checkpoint.Name
					workspace.SoundFx.Success:Play()
					Event.CheckPointEvent:FireClient(Player)
				end
			end
		end)
		
		Player.CharacterAdded:Connect(function(Character)
			repeat
				wait()
			until Character ~= nil
			
			local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
			HumanoidRootPart.CFrame = CheckpointsFolder:FindFirstChild(Stage.Value).CFrame + Vector3.new(0, 2, 0)
		end)
	end
end)

I am quite new to scripting and I have no idea what the issue is. :face_with_diagonal_mouth:

5 Likes

Hey, if your variable named players is highlighted it’s because it can’t access / does not exist.

Edit : I’ll check your code on studio so I can see it better

1 Like

I changed a bit your code (skip stage script, the first one you posted), tell me if it has changed anything now.

MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService.ProcessReceipt = function(receiptInfo)
	local players = game.Players:GetPlayers()

	local currency = "Stage"

	local done = 0

	for i=1,#players do
		if players[i].userId == receiptInfo.PlayerId then
			if receiptInfo.ProductId == 16231369024 and done == 0 then
				done = 1
				players[i].leaderstats[currency].Value = players[i].leaderstats[currency].Value + 1
				players[i].Character.Humanoid.Health = 0
				done = 0
			end
		end
	end
	return Enum.ProductPurchaseDecision.PurchaseGranted	
end

Here you forgot an “s” to the variable player, and I changed the global variables to local ones.

2 Likes

Also, can you put a screenshot of your explorer → workspace Folders, ReplicatedStorage Events please

It’ll be faster to see what’s the issue here

Hey! I’ll try it out in the morning and then let you know if it works! :+1:

Alright, I’ll try to debug you code and replicate what’s needed in you scripts in the meantime :wink:

There you go!
replicated

That’s what I’ve made, the more you share about your issue, the easier and faster it is for us to solve it!
Things like part’s names, folders, … in the explorer is always appreciated when your script uses them

If it helps then here’s also the script that I used on my checkpoint parts.

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

local checkpoint = script.Parent

function onTouched(hit)
	if hit and hit.Parent and hit.Parent:FindFirstChildOfClass("Humanoid") then
		local player = Players:GetPlayerFromCharacter(hit.Parent)
		local checkpointData = ServerStorage:FindFirstChild("CheckpointData")
		if not checkpointData then
			checkpointData = Instance.new("Folder")
			checkpointData.Name = "CheckpointData"
			checkpointData.Parent = ServerStorage
		end

		local userIdString = tostring(player.UserId)
		local checkpointValue = checkpointData:FindFirstChild(userIdString)
		if not checkpointValue then
			checkpointValue = Instance.new("ObjectValue")
			checkpointValue.Name = userIdString
			checkpointValue.Parent = checkpointData

			player.CharacterAdded:connect(function(character)
				wait()
				local storedCheckpoint = ServerStorage.CheckpointData[userIdString].Value
				character:MoveTo(storedCheckpoint.Position + Vector3.new(math.random(-4, 4), 4, math.random(-4, 4)))
			end)
		end

		checkpointValue.Value = checkpoint
	end
end

checkpoint.Touched:Connect(onTouched)
2 Likes

Considering you have a stage 0 checkpoint, I changed a few things and got no error in my output.
If you still encounter any issues, I’d love to try to replicate them to help you.

local Rs = game.ReplicatedStorage
local Event = Rs:WaitForChild("Events")

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Parent = Player
	leaderstats.Name = "leaderstats"

	local Stage = Instance.new("NumberValue")
	Stage.Parent = leaderstats
	Stage.Name = "Stage"
	Stage.Value = 0

	local CheckpointsFolder = game.Workspace:FindFirstChild("Checkpoints")

	for i, Checkpoint in pairs(CheckpointsFolder:GetChildren()) do

		Checkpoint.Touched:Connect(function(Hit)
			if Hit.Parent:FindFirstChild("Humanoid") then
				local PlayerHit = game.Players:GetPlayerFromCharacter(Hit.Parent)
				if PlayerHit.leaderstats:FindFirstChild("Stage").Value == tonumber(Checkpoint.Name) - 1 then
					PlayerHit.leaderstats:FindFirstChild("Stage").Value = Checkpoint.Name
					workspace.SoundFx.Success:Play()
					Event.CheckPointEvent:FireClient(Player)
				end
			end
		end)

		Player.CharacterAdded:Connect(function(Character)
			repeat
				task.wait()
			until Character ~= nil
			local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
			local index = tostring(Stage.Value)
			HumanoidRootPart.CFrame = CheckpointsFolder:FindFirstChild(index).CFrame + Vector3.new(0, 2, 0)
		end)
	end
end)

On your first post, the error
ServerScriptService.CheckpointScript:23: attempt to perform arithmetic (sub) on string and number
is explicit. Use tonumber(<string>) before performing any arithmetic operations.

For this ServerScriptService.CheckpointScript:37: attempt to index nil with ‘CFrame’, I used tostring(Stage.Value) since Stage.value is a numerical value.

Edit: I’ll surely reply to you tomorrow, if nobody does before me :wink:(I’ve also removed my useless prints, it was to debug your script, that’s the tip.)

Hey I tried it and for some reason I am still getting these error messages. Skip stage script just still doesn’t function although nothing is highlighted in this script now.

And these are the error messages that are being displayed in output over and over again.

ServerScriptService.CheckpointScript:21: attempt to perform arithmetic (sub) on nil and number

ServerScriptService.CheckpointScript:35: attempt to index nil with ‘CFrame’

Checkpoint script works technically but It still has some mistakes in it. Here’s the script that I am using on my Skip Stage button to display the purchasing option, but that works.

local productId = 1623136902
local player = game.Players.LocalPlayer
script.Parent.MouseButton1Click:connect(function()
	game:GetService("MarketplaceService"):PromptProductPurchase(player, productId)
end)

For the CheckpointScript, I can’t replicate your error. Make sure everything is in order.

In the Workspace:
image

ReplicatedStorage:
image

1 Like

Thanks I found the issue! My first checkpoint was 1 instead of 0 so I changed it and it works now! Do you have any ideas what could be the problem with the skip stage script though?

why do you get the player like that?
u can just

local player = players:GetPlayerByUserId(receiptInfo.PlayerId)

if not player then 
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

so here is my script, correct me if there’s something wrong

local function processReceipt(receiptInfo)
local player = players:GetPlayerByUserId(receiptInfo.PlayerId)

if not player then 
	return Enum.ProductPurchaseDecision.NotProcessedYet
end
if receiptInfo.ProductId == 1585407367 then
	if player then 
		player.leaderstats.Stage.Value += 1 
		player:LoadCharacter()
	end
end

return Enum.ProductPurchaseDecision.PurchaseGranted

end

MarketplaceService.ProcessReceipt = processReceipt

I changed some stuff in this code and tried it but it still doesn’t work for me. The script isn’t written entirely by me I just changed it a bit because I am not very experienced.

MarketplaceService = game:GetService("MarketplaceService")

local function processReceipt(receiptInfo)
	
	local players = game.Players:GetPlayers()
	
local player = players:GetPlayerByUserId(receiptInfo.PlayerId)

if not player then 
	return Enum.ProductPurchaseDecision.NotProcessedYet
end
	if receiptInfo.ProductId == 16231369024 then
	if player then 
		player.leaderstats.Stage.Value += 1 
		player:LoadCharacter()
	end
end

return Enum.ProductPurchaseDecision.PurchaseGranted

end

MarketplaceService.ProcessReceipt = processReceipt

Im so confused because it worked half of the time before and I don’t think I changed anything in the script (also why would it work only like 50% of the time it doesn’t make any sense to me).

1 Like

I’ll check it later, I have to do, but I’ll be back as soon as possible if nobody already solves it :smile:

1 Like

bro its not

local players = game.Players:GetPlayers()

its

local players = game:GetService("Players")

and you should put that variable outside of the processReceipt function…

1 Like
MarketplaceService = game:GetService("MarketplaceService")

local players = game:GetService("Players")

local function processReceipt(receiptInfo)
	
local player = players:GetPlayerByUserId(receiptInfo.PlayerId)

if not player then 
	return Enum.ProductPurchaseDecision.NotProcessedYet
end
	if receiptInfo.ProductId == 16231369024 then
	if player then 
		player.leaderstats.Stage.Value += 1 
		player:LoadCharacter()
	end
end

return Enum.ProductPurchaseDecision.PurchaseGranted

end

MarketplaceService.ProcessReceipt = processReceipt

Still doesn’t work. :face_with_diagonal_mouth:

Skip Stage Script: The skip stage script you provided seems to have a few issues, mainly due to variable typos and incorrect usage of variables. Here’s a corrected version of the script:

local MarketplaceService = game:GetService("MarketplaceService")

MarketplaceService.ProcessReceipt = function(receiptInfo)
    local players = game.Players:GetPlayers()

    local currency = "Stage"
    local done = false

    for i = 1, #players do
        if players[i].UserId == receiptInfo.PlayerId then
            if receiptInfo.ProductId == 16231369024 and not done then
                done = true
                players[i].leaderstats[currency].Value = players[i].leaderstats[currency].Value + 1
                players[i].Character:BreakJoints()
                done = false
            end
        end
    end

    return Enum.ProductPurchaseDecision.PurchaseGranted
end

Checkpoint Script: Your checkpoint script seems to be mostly correct, but there are a couple of adjustments needed:

  1. The issue you’re facing with the error message “attempt to perform arithmetic (sub) on string and number” is likely due to the line if PlayerHit.leaderstats:FindFirstChild("Stage").Value == Checkpoint.Name - 1 then. The Checkpoint.Name is a string, and you need to convert it to a number before performing arithmetic operations. Replace it with tonumber(Checkpoint.Name) - 1.
  2. In the CharacterAdded event, you’re using CheckpointsFolder:FindFirstChild(Stage.Value) to access the checkpoint’s CFrame. Instead, you should use Checkpoint.CFrame.

Here’s the 'CheckpointScript`:

local Rs = game.ReplicatedStorage
local Event = Rs:WaitForChild("Events")

game.Players.PlayerAdded:Connect(function(Player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Parent = Player
    leaderstats.Name = "leaderstats"

    local Stage = Instance.new("NumberValue")
    Stage.Parent = leaderstats
    Stage.Name = "Stage"
    Stage.Value = 0

    local CheckpointsFolder = game.Workspace:FindFirstChild("Checkpoints")

    for i, Checkpoint in pairs(CheckpointsFolder:GetChildren()) do
        Checkpoint.Touched:Connect(function(Hit)
            if Hit.Parent:FindFirstChild("Humanoid") then
                local PlayerHit = game.Players:GetPlayerFromCharacter(Hit.Parent)
                if PlayerHit and PlayerHit.leaderstats:FindFirstChild("Stage").Value == tonumber(Checkpoint.Name) - 1 then
                    PlayerHit.leaderstats:FindFirstChild("Stage").Value = tonumber(Checkpoint.Name)
                    workspace.SoundFx.Success:Play()
                    Event.CheckPointEvent:FireClient(PlayerHit)
                end
            end
        end)

        Player.CharacterAdded:Connect(function(Character)
            repeat
                wait()
            until Character:FindFirstChild("HumanoidRootPart")

            local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
            HumanoidRootPart.CFrame = Checkpoint.CFrame + Vector3.new(0, 2, 0)
        end)
    end
end)

After making these changes, your scripts should function more accurately. Remember to always carefully check your variable names, data types, and syntax to avoid such issues.

1 Like