Checkpoint System Error

Hello!

I’m creating a game.

Within it, I’m trying to create a checkpoint system that will do the following:

  • List the player’s stage in leaderstats
  • Allow the player to respawn at their last checkpoint if they die
  • Save when the player comes back, and respawn them at their last checkpoint

I used this tutorial by @xuefei123 (which, for the most part, worked fine).

Note: I didn’t copy the entire checkpoint script, just the gist of it. I also made the second script from the video a LocalScript since I had to do some UI scripting (it didn’t make a difference).

Recently, I added 2 values to my game (skips and game currency) that were updated and saved using DataStore2.

Since data stores can only be accessed from the server, I used RemoteEvents. Those worked fine, and the currency and skips were updating correctly.

However, around this time, my checkpoint script(s) began to… stop working? I’m still pretty new to scripting, so I can’t figure out why.

When I complete or skip a stage, the leaderstats update accurately according to the checkpoint I’m on. If I die though, I’m respawned all the way at the start (leaderstats stay the same). I still earn my currency for completing a stage, and that saves, but the checkpoints won’t. Plus, when I rejoin, it starts spawning me back at the beginning, and the leaderstats reset.

Like I mentioned above, I’m not sure what’s going on, but I feel like it has something to do with the saving of other values or the RemoteEvents. I would greatly appreciate any assistance.

Script (saves checkpoint values)
local players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local saveDataStore = DataStoreService:GetDataStore("ClassicObbyAdventuresDataStore")

local function savePlayerData(player)
	
	local success,err = pcall (function()
	
		local saveData = {}
		
		for _,stat in pairs(player.leaderstats:GetChildren()) do
			
			saveData[stat.Name] = stat.Value
			
		end
		
		saveDataStore:SetAsync(player.UserId,saveData)
		
	end)	
	
	if not success then return err end
	
end

players.PlayerAdded:Connect(function(player)
	
	local stats = Instance.new("Folder")
	stats.Name = "leaderstats"
	stats.Parent = player
	
	local stage = Instance.new("IntValue")
	stage.Name = "Stage"
	stage.Parent = stats
	
	local data = saveDataStore:GetAsync(player.UserId)
	
	if data then
		
		print(player.Name.. " has joined the game. They have spawned at stage "..data.Stage..".")
		
		for _,stat in pairs(stats:GetChildren()) do
			
			stat.Value = data[stat.Name]
			
		end
		
	else
		
		print(player.Name.." either has no data or their data has not been loaded.")	
		
	end
	
	player.CharacterAdded:Connect(function(character)
		
		local humanoid,hrp = character:WaitForChild("Humanoid"),character:WaitForChild("HumanoidRootPart")
		
		wait()
		
		if humanoid and hrp then
			
			if stage.Value ~= 0 then
				
				local part = workspace.ObbyStages:FindFirstChild(stage.Value)
				hrp.CFrame = part.CFrame + Vector3.new(0,1,0)
				
			end
			
		end
		
	end)
	
end)

players.PlayerRemoving:Connect(function(player)
	
	local err = savePlayerData(player)
	
	if err then print(err) end
	
end)

game:BindToClose(function()
	
	for _,player in pairs(players:GetPlayers()) do
		
		local err = savePlayerData(player)
		
		if err then print(err) end
		
	end
	
	wait(2)
	
end)
LocalScript (teleports player to designated checkpoint + UI handling)
local obbyStages = workspace:WaitForChild("ObbyStages")

local Add10TicketsEvent = game.ReplicatedStorage.Add10Tickets

for _,stage in pairs(obbyStages:GetChildren()) do
	
	stage.Touched:Connect(function(hit)
		
		local hum
		
		if hit.Parent:FindFirstChild("Humanoid") then
			
			hum = hit.Parent.Humanoid
			
		end
		
		if hit.Parent and hit.Parent.Parent:FindFirstChild("Humanoid") then
			
			hum = hit.Parent.Parent.Humanoid
			
		end
		
		if hum then
			
			local player = game.Players:GetPlayerFromCharacter(hum.Parent)
			
			local plrStage = player.leaderstats.Stage.Value
			
			local sound = game.ReplicatedStorage.LevelCompleted
						
			if tonumber(stage.Name) == plrStage + 1 then
				
				player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
				
				script.Parent.TicketsGui.AddedTickets.Text = "+10"
				
				Add10TicketsEvent:FireServer()
				
				sound:Play()
				
				script.Parent.TicketsGui.AddedTickets.Visible = true
				
				wait(2.5)
				
				script.Parent.TicketsGui.AddedTickets.Visible = false
				
			elseif tonumber(stage.Name) > plrStage + 1 then
				
				hum.Health = 0	
				
				script.Parent.MissedCheckpoint.Enabled = true
				
			elseif tonumber(stage.Name) < plrStage then
				
				script.Parent.WrongWayNotification.Frame.TextLabel.Text = "Wrong Way!" 
				
				script.Parent.WrongWayNotification.Frame.TextLabel.TextScaled = true
				
				script.Parent.WrongWayNotification.Enabled = true
				
				wait(3)
				
				script.Parent.WrongWayNotification.Enabled = false	
				
			end
			
		end
		
	end)
	
end

If you have any questions regarding my scripts or objects mentioned in them, feel free to ask. The same thing goes for additional information - just ask!

Have a great day/night.

2 Likes

I’ve been having this problem. Whenever I Change a value inside of the player and leave. My datastore only saves sometimes (yes im using pcall).

2 Likes

You’re updating the stage value in a localscript. Checked your datastore script and it saved fine for me.

I think it might not be saving because you’re changing the stage value on the client instead of the server. Maybe have the localscript code in a normal script?

2 Likes

Sometimes datastores fail to save and then don’t save causing players to lose progress

1 Like

I see what you’re trying to say, @royaltoe, but like I said, the LocalScript worked fine.

It stopped working around the point where I added RemoteEvents to the script that updated values. I’ll try your suggestion and see if it works (it might take a while because I have to reverse the RemoteEvents and stuff).

1 Like

Wow, um, it worked. The stage values are updating and saving fine now.

For some reason though, my RemoteEvents either aren’t being picked up or aren’t firing.

This is the LocalScript which I converted into a Script:

local obbyStages = workspace:WaitForChild("ObbyStages")

local WrongWayNotificationEvent = game.ReplicatedStorage.WrongWayNotification

local MissedCheckpointEvent = game.ReplicatedStorage.MissedCheckpoint

local AddTicketsEvent = game.ReplicatedStorage.Add10Tickets

for _,stage in pairs(obbyStages:GetChildren()) do
	
	stage.Touched:Connect(function(hit)
		
		local hum
		
		if hit.Parent:FindFirstChild("Humanoid") then
			
			hum = hit.Parent.Humanoid
			
		end
		
		if hit.Parent and hit.Parent.Parent:FindFirstChild("Humanoid") then
			
			hum = hit.Parent.Parent.Humanoid
			
		end
		
		if hum then
			
			local player = game.Players:GetPlayerFromCharacter(hum.Parent)
			
			local plrStage = player.leaderstats.Stage.Value
			
			local sound = game.ReplicatedStorage.LevelCompleted
			
			if tonumber(stage.Name) == plrStage + 1 then
				
				player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
				
				sound:Play() -- this sound isn't playing
				
				AddTicketsEvent:FireClient() -- not working
				
			elseif tonumber(stage.Name) > plrStage + 1 then
				
				MissedCheckpointEvent:FireClient() -- not working
								
			elseif tonumber(stage.Name) < plrStage then
				
				WrongWayNotificationEvent:FireClient() -- not working
				
			end
			
		end
		
	end)
	
end

As you can see, I’m firing 3 RemoteEvents to the client, all of which aren’t being picked up or aren’t being fired in the first place. There’s also a sound that’s supposed to play in my code just before I fire the AddTicketsEvent to the client, but it isn’t.

RemoteEvent LocalScript
local WrongWayNotificationEvent = game.ReplicatedStorage.WrongWayNotification

local MissedCheckpointEvent = game.ReplicatedStorage.MissedCheckpoint

local AddTicketsEvent = game.ReplicatedStorage.Add10Tickets

local function onWrongWayNotificationFired()
	
	script.Parent.WrongWayNotification.Frame.TextLabel.Text = "Wrong Way!" 
	
	script.Parent.WrongWayNotification.Frame.TextLabel.TextScaled = true
	
	script.Parent.WrongWayNotification.Enabled = true
	
	wait(3)
	
	script.Parent.WrongWayNotification.Enabled = false	
	
end

local function onMissedCheckpointFired()
	
	local player = game.Players.LocalPlayer
	
	local character = player.Character
	
	local humanoid = player.Character:FindFirstChild("Humanoid")
	
	humanoid.Health = 0
	
	script.Parent.MissedCheckpoint.Enabled = true
	
end

local function onAddTicketsFired()
	
	script.Parent.TicketsGui.AddedTickets.Text = "+10"
	
	script.Parent.TicketsGui.AddedTickets.Visible = true
	
	wait(2.5)
	
	script.Parent.TicketsGui.AddedTickets.Visible = false
	
end

WrongWayNotificationEvent.OnClientEvent:Connect(onWrongWayNotificationFired)
MissedCheckpointEvent.OnClientEvent:Connect(onMissedCheckpointFired)
AddTicketsEvent.OnClientEvent:Connect(onAddTicketsFired)

So the saving of the checkpoints is working fine, yet now the RemoteEvents which I switched to be fired from the server don’t seem to be working. Any help would be appreciated. Thank you!

3 Likes

For FireClient, you have to pass which client you’re firing to as the first parameter.

In your case it would be:

:FireClient(player)
1 Like

Here, use this system: Obby Tutorial - Roblox

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.