Hello! I'm making an obby and I have several problems with my code. First of all, my script is meant to display the player's stage on the leaderboard, and it works, however the stage value won't increase when touching another checkpoint, it just stays at 1. Whenever I touch a checkpoint an error shows up reading, "ServerScriptService.StageScript:23: attempt to index nil with 'leaderstats'".
Here's the script.
local Stages = workspace:WaitForChild("Stages")
for i,Stage in pairs(Stages:GetChildren()) do
Stage.Touched:Connect(function(touch)
local humanoid
if touch.Parent:FindFirstChild("Humanoid") then
humanoid = touch.Parent.Humanoid
end
if touch.Parent and touch.Parent.Parent:FindFirstChild("Humanoid") then
humanoid = touch.Parent.Parent.Humanoid
end
if humanoid then
local player = game.Players:GetPlayerFromCharacter(humanoid.Parent)
local PlayerStage = player.leaderstats.Stage.Value
if tonumber(Stage.Name) == PlayerStage + 1 then
player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
elseif tonumber(Stage.Name) > PlayerStage + 1 then
humanoid.Health = 0
end
end
end)
end
Secondly, I also have an autosaving script to save the player's stage so when they rejoin, they will be at the stage they were at when they left. I'm not sure if it works as the stage value stays at 1. However, I know it's part of the problem because the player's "leaderstats" folder is created here.
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local SaveDataStore = DataStoreService:GetDataStore("SaveData")
local function SavePlayerData(player)
local success,errormsg = pcall(function()
local SaveData = {}
for i,stats in pairs(player.leaderstats:GetChildren()) do
SaveData[stats.Name] = stats.Value
end
SaveDataStore:SetAsync(player.UserId,SaveData)
end)
if not success then
return errormsg
end
end
Players.PlayerAdded:Connect(function(player)
local Stats = Instance.new("Folder")
Stats.Name = "leaderstats"
Stats.Parent = player
local Stage = Instance.new("StringValue")
Stage.Name = "Stage"
Stage.Parent = Stats
Stage.Value = 1
local Data = SaveDataStore:GetAsync(player.UserId)
if Data then
print(Data.Stage)
for i,stats in pairs(Stats:GetChildren()) do
stats.Value = Data[stats.Name]
end
else
print(player.Name .. " has no data.")
end
player.CharacterAdded:Connect(function(character)
local Humanoid = character:WaitForChild("Humanoid")
local Torso = character:WaitForChild("HumanoidRootPart")
wait()
if Torso and Humanoid then
if Stage.Value ~= 0 then
local StagePart = workspace.Stages:FindFirstChild(Stage.Value)
Torso.CFrame = StagePart.CFrame + Vector3.new(0,1,0)
end
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
local errormsg = SavePlayerData(player)
if errormsg then
warn(errormsg)
end
end)
game:BindToClose(function()
for i,player in pairs(Players:GetPlayers()) do
local errormsg = SavePlayerData(player)
if errormsg then
warn(errormsg)
end
end
wait(2)
end)

2 comments
This works, thank you!
No problem.