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.
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.
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)
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 (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)
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?
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).
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
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:
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.
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.