Yo, I’m a beginner dev and if y’all don’t mind I need a little assistance with a script here. Very rarely, when a player loads into the game on stage 1, they go to touch stage 2 and remain on stage 1 until resetting. I believe it started happening when I added my “checkpoint sounds” local script and I’ll see what happens if I remove/tamper with that. I haven’t touched the checkpoint script since around May. But I just need to know what’s going on with it down below:
local checkpoints = workspace:WaitForChild("Checkpoints")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DatastoreService = game:GetService("DataStoreService")
local Data = DatastoreService:GetDataStore("1")
local sessionData = {}
function PlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
local stage = Instance.new("NumberValue")
stage.Name = "Stage"
stage.Parent = leaderstats
local success = nil
local playerData = nil
local attempt = 1
repeat
success, playerData = pcall(function() -- here pcall or protected call is just repeat waiting until the data loads for the player
return Data:GetAsync(player.UserId)
end)
attempt += 1
if not success then
warn(playerData)
task.wait(2)
end
until success or attempt == 5 -- it repeats it until it loads
if success then --if it loads then make the table with their data inside
print("Data loaded: "..player.Name)
if not playerData then -- if they have no table then they're a new player so we create the table
print("new player, giving default data")
playerData = {
["Stage"] = 1, --add all your values and stuff inside of the data
}
end
sessionData[player.UserId] = playerData --set the data to a table with the players id and make to make a variable
else
warn("couldnt load data: "..player.Name)
player:Kick("couldnt load your data, rejoin") --if the data couldnt load we kick them so their not just sitting there forever waiting
end
stage.Value = sessionData[player.UserId].Stage --here we get the numbervalue created above and get the value of it and set it to the value inside of the table
stage:GetPropertyChangedSignal("Value"):Connect(function()
sessionData[player.UserId].Stage = stage.Value --update the table value whenever the leaderstat value changes
end)
leaderstats.Parent = player
end
Players.PlayerAdded:Connect(function(player)
PlayerAdded(player)
player.CharacterAdded:Connect(function(char)
local leaderstats = player:WaitForChild("leaderstats")
local stage = leaderstats.Stage
local hum = char:WaitForChild("Humanoid")
task.wait()
char:MoveTo(checkpoints[stage.Value].Position)
hum.Touched:Connect(function(hit)
if hit.Parent == checkpoints then
if tonumber(hit.Name) == stage.Value + 1 then
stage.Value += 1
end
end
end)
end)
end)
function PlayerLeaving(player)
if sessionData[player.UserId] then
local success = nil
local errorMsg = nil
local attempt = 1
repeat
success, errorMsg = pcall(function()
Data:SetAsync(player.UserId, sessionData[player.UserId]) --here is the same as loading data just repeat waits until the data saves
end)
attempt += 1
if not success then
warn(errorMsg)
task.wait(2)
end
until success or attempt == 5
if success then
print("Data saved: "..player.Name)
else
warn("Cant save: "..player.Name)
end
end
end
Players.PlayerRemoving:Connect(PlayerLeaving)
function ServerShutdown()
if RunService:IsStudio() then
return
end
for i, player in ipairs(Players:GetPlayers()) do
task.spawn(function()
PlayerLeaving(player)
end)
end
end
game:BindToClose(ServerShutdown)
– Define the checkpoint object
local Checkpoint = {}
Checkpoint.__index = Checkpoint
– Constructor function for creating a new checkpoint
function Checkpoint.new(position)
local self = setmetatable({}, Checkpoint)
self.position = position
self.activated = false
return self
end
– Function to check if a player has reached the checkpoint
function Checkpoint:playerReached(playerPosition)
local distance = (playerPosition - self.position).Magnitude
return distance < 5 – Adjust the distance threshold as needed
end
– Function to activate the checkpoint for a player
function Checkpoint:activate()
self.activated = true
print(“Checkpoint activated!”)
end
– Sample usage:
– Create a checkpoint at a specific position
local checkpoint1 = Checkpoint.new(Vector3.new(10, 0, 0))
– Simulate a player reaching the checkpoint
local playerPosition = Vector3.new(9, 0, 0)
if checkpoint1:playerReached(playerPosition) then
checkpoint1:activate()
end
repeat
success, result = pcall(function() -- here pcall or protected call is just repeat waiting until the data loads for the player
local data = Data:GetAsync(player.UserId)
playerData = data
return data
end)
attempt += 1
if not success then
warn(result)
task.wait(2)
end
until success or attempt == 5
Alright this works perfectly, i rejoined a few times and tested it out! Only problem is it doesn’t save the progress anymore when the person leaves. Like if they leave on stage 50 they’ll be there when they join back! Any idea how to fix that, actually is that even needed? What I’m worried about is if somebody leaves on stage 100 and they wanna finish my game, if it kicks them all the way back to stage 1 will they get upset about it?
All good mane, nothing wrong with us being new. I’m happy y’all are all being helpful because other people just tell me “remoteevent this, boolean that”
Still doesn’t save BUT that’s fine mane! Hell, I’m just happy that the checkpoints aren’t bugging anymore. It isn’t a really long thousand stage obby anyways so I’m sure most players won’t mind when I start advertising. Thank y’all for your help though! Also, Merry late Christmas and wish y’all a wonderful 2024
Yo Mort, I ran into the same problem again after leaving and rejoining the game like 20 times but it’s still very rarely. Any idea on how to fix it completely or should i just redo the whole checkpoint script? I brought 10 friends in the game and it worked fine.
Sometimes datastoreservice doesnt save things due to some sort of error or rate issues. You will just have to retry it if it doesn’t save, or accept how it is since it is really rare.