Help making a checkpoint system

perhaps you could explain what each step you did does? And what you wrote means, as he might be newer. Even I don’t understand what this means.

  1. That just requires a module… It doesn’t run any functions or anything.
  2. They want to know how to script it, not to use some random module script.

Alright I shall explain.

The require() gets a module script that is responsible for the checkpoint script.

This is the code in the module,

local module = {}

--Adding and loading data

-- variables
local folder = workspace:WaitForChild("CheckpointsFolder")
local prts = {}


for _,x in pairs(folder:GetChildren())do
	if x:IsA("BasePart") then
		table.insert(prts, x)
	end
end

print("load")


local players = game:GetService("Players")
local dataStore = game:GetService("DataStoreService")
local myData = dataStore:GetDataStore("^%%58765^%$5")


for _,x in pairs(players:GetChildren())do
	local leaderstats
	if x:FindFirstChild("leaderstats") then
		leaderstats = x:FindFirstChild("leaderstats")
	else
		leaderstats = Instance.new("Folder", x)
		leaderstats.Name = "leaderstats"
	end

	local level = Instance.new("IntValue", leaderstats)
	level.Name = "Level"

	local d

	local s,e = pcall(function()
		d = myData:GetAsync(x.UserId)
	end)

	if s then
		level.Value = d
	else
		warn(e)
	end

	local char = x.Character or x.CharacterAdded:Wait()
	print("Character added")

	for _,c in pairs(prts)do

		if c.Name == tostring(level.Value) then
			print('a')
			wait(.1)
			local leftFoot = char:FindFirstChild("HumanoidRootPart")
			print(leftFoot)
			leftFoot.CFrame = c.CFrame * CFrame.new(0,10,0)
		end
	end


	x.CharacterAdded:Connect(function(char1)
		print("Character added")

		for _,c in pairs(prts)do

			if c.Name == tostring(level.Value) then
				print('a')
				wait(.1)
				local leftFoot = char1:FindFirstChild("HumanoidRootPart")
				print(leftFoot)
				leftFoot.CFrame = c.CFrame * CFrame.new(0,10,0)
			end
		end
	end)

end

players.PlayerAdded:Connect(function(plr)
	
	local leaderstats
	if plr:FindFirstChild("leaderstats") then
		leaderstats = plr:FindFirstChild("leaderstats")
	else
		leaderstats = Instance.new("Folder", plr)
		leaderstats.Name = "leaderstats"
	end
	
	local level = Instance.new("IntValue", leaderstats)
	level.Name = "Level"

	local d

	local s,e = pcall(function()
		d = myData:GetAsync(plr.UserId)
	end)

	if s then
		level.Value = d
	else
		warn(e)
	end

	plr.CharacterAdded:Connect(function(char)
		print("Character added")
		for _,c in pairs(prts)do

			if c.Name == tostring(level.Value) then
				print('a')
				wait(.1)
				local leftFoot = char:FindFirstChild("HumanoidRootPart")
				print(leftFoot)
				leftFoot.CFrame = c.CFrame * CFrame.new(0,10,0)
			end
		end
	end)
end)

players.PlayerRemoving:Connect(function(plr)
	local l = plr:WaitForChild("leaderstats")
	local lvl = l:WaitForChild("Level")
	local lvlVal = lvl.Value
	local plrID = plr.UserId

	local s,e = pcall(function()
		myData:SetAsync(plrID, lvlVal)
	end)

	if s then
		warn(plr.Name .. "'s level data was saved to " .. tostring(lvlVal))
	else
		warn(e)
	end
end)


for c = 1,#prts do
	prts[c].Touched:Connect(function(Hit)
		if Hit.Parent:FindFirstChildWhichIsA("Humanoid") then
			local char = Hit.Parent
			local plr = players:GetPlayerFromCharacter(char)
			local lead = plr:WaitForChild("leaderstats")
			local lvl = lead:WaitForChild("Level")
			local lvlVal = lvl.Value
			local partVal = tonumber(prts[c].Name)
			if partVal > lvlVal then
				lvl.Value = partVal
			end
		end

	end)
end

return module

the folder gets the parts in the checkpoint folder, the parts table is the table used to filter out the objects in the folder to make sure that they are not anything but a base part(part/mesh part). The loop adds all the parts to the table.

the print was just for me when I was testing to make sure everything worked.

Next, I got some variables including the data store and the data store that would be used to save the points.

I looped through the players at the beginning because the module takes some time to load and a player would have already been in the game.

Then I made it so that when a new player is added they have their points loaded and the level value is added.

I used the removing player to save the player’s points when they left the game.

For the final part, I looped through all the parts in the table and made it so that if you touch them, it will check if you are a level ahead of it and if you are not it will set your level to that value.

If you have any other questions on what I did in here please ask.

Here is a game I made quickly of it in use.
(2) Checkpoint Test - Roblox

1 Like

The Checkpoint Test game is not functioning as it is supposed to. When you reset it does not respawn you at the correct spawn.

Btw, thank you so much for taking the time to help me with this it means a lot.

Oh, sorry about that. I completely forgot about that.

I’ll update the module so it will work.

local module = {}

local iss = game:GetService("InsertService")

local id = 0

local asId = iss:LoadAsset(id)

return module

What is this new script?
Am I missing something?

Oh yeah, I am trying to figure out an issue I ran into. I am making the CFrame of a character’s foot that of the checkpoint, but it is not teleporting it there.

Use HumanoidRootPart, not body parts so it is compatible with R15 and R6.
You should probably also make the player appear a few studs above the checkpoint rather than inside it so they aren’t flung.

I reverted the code back to the old code, added the teleport feature. Try it now, it should work.

How do I setup the checkpoints?

(The parts that you respawn at)

Add a Folder into the workspace and name it “CheckpointsFolder”. To add in a part you put the part into the folder and name it what level it is so if the checkpoint is for level 1 you name the brick “1”. In the Checkpoint text game, you can get a copy of it at the top right corner where the three dots are.

I think I’m doing everything right but, it’s still not working…
Do you know what’s wrong?

Dev forum pic 10

Nevermind, I found the problem. I forgot to put in the Loader.

Just for learning, would you tell me what the Loader does?

While I’ll show you how I would set up a checkpoint zone, I won’t elaborate on how you can save data, you can check out a tutorial on how to do that: https://www.youtube.com/watch?v=-wAJAI95ivs

First I would acquire the ZonePlus v2 module and install it into studio (See installation guide on how to)
https://devforum.roblox.com/t/zoneplus-v2-construct-dynamic-zones-and-effectively-determine-players-and-parts-within-their-boundaries/1017701

Then I would code the following

CheckpointVal=Instance.New("IntValue")--adds an IntVal to game
CheckpointVal.Parent = Player--sets Parent of the value to the player
--using zone v2 functions/methods/events (in this case an event) obtain Zone's modulescript in replicated storage(see installation walkthrough)
local Zone = require(game:GetService("ReplicatedStorage").Zone)
--initialize a zonegroup, i.e. checkpoints, zones must be something a player
--touches or passes through.
local Checkpoint1zone = game.Workspace.Obbymap.CheckPoint1--Location of Block in which you want the player to pass into for checkpoint1
local Checkpoint2zone = game.Workspace.Obbymap.CheckPoint2--Location of Block in which you want the player to pass into for checkpoint2
local Checkpoint1 = Zone.new(Checkpoint1zone)
local Checkpoint2 = Zone.new(Checkpoint2zone)
--categorizes the checkpointzones on map as a actual zone within ZonePlus v2 module

--Checks on player entering, who that player was
Checkpoint1.playerEntered:Connect(function(player)--obtains player
player.CheckpointVal=1	--sets val of checkpoint intval to 1
--player that entered gets their intval set to 1
end)

--and since you dont need to check if playerExited don't need to worry about it just keep checking what player enters what zone

--Checks on player entering the zone what player was it, obtains player, and puts Checkpoint2
Checkpoint2.playerEntered:Connect(function(player)--obtains player
player.CheckpointVal=2--sets val of checkpoint intval to 2
--player that entered gets their intval set to 2
end)

As I said before, I won’t elaborate on saving data, you’ll have to fetch the value of player’s checkpointval and then save it to his player id. Something along those lines, you’ll also want to fetch the player’s checkpointval and assign a spawn point to them somehow, perhaps using teams function? i.e. have checkpoints as teams and then have spawn points for those checkpoints and if this is the case, you can go ahead and just set player team to checkpoint# team on enter. IDK you do you dude

I’m not the author of the module, but after reading through it:
Basically, it loops through all the parts in the folder in workspace. It puts them in a table for later use. After that, it gets a DataStore to save and get the Player’s checkpoint (later use). Then, it loops through all the players and adds leaderstats to them (I recommend using game.Players.PlayerAdded instead). It then gets the saved value from the DataStore, using a pcall so if it errors, the script doesn’t stop.

At the PlayerRemoving event, it gets the user’s ID, level, stuff like that for saving. It then saves the player’s level. After that, the for c = loop loops through all the parts in the table made earlier. It gets the player’s stats. It checks if the checkpoints value/level is larger than the player’s current level (so they don’t accidentally move down a stage), and if it is, sets that to their level.

1 Like

Wow! Thank you, that really helps me.

1 Like

Whenever I make new obbies, I create a folder named Checkpoints where you insert a script inside of the folder. You then make a new part named 1, etc. After you have done that, you make a normal leaderstats script which then gets your checkpoint value. This will allow you to respawn at the current checkpoint you’re at.

Leaderstats:

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

	local checkpoints = Instance.new("IntValue", leaderstats)
	checkpoints.Name = "Checkpoint"
	checkpoints.Value = 1


	player.CharacterAdded:Connect(function(Character)
		repeat wait() until player.Character ~= nil
		local checkpoint = workspace.Checkpoints:FindFirstChild(checkpoints.Value)
		Character:WaitForChild("HumanoidRootPart").CFrame = CFrame.new(checkpoint.Position + Vector3.new(0,2,0)) -- Teleports you to the checkpoint you last was at.

	end)
	wait(3)
	player:LoadCharacter()
end)

Inside checkpoints folder

local Checkpoints = script.Parent

for i,v in pairs(Checkpoints:GetChildren()) do
	if v:IsA("BasePart") then
		v.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") then 
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			if player then
				if player.leaderstats.Checkpoint.Value < tonumber(v.Name) then
						player.leaderstats.Checkpoint.Value = tonumber(v.Name)
					end
					
				end
			end
		end)
	end
end

Should then look like this in the checkpoint Folder

sdfsdfsdsfdssd

1 Like

Thank you for the script but I already have a working one from deafaultyboii1324 Just one thing, when I use the script by deafaultyboii1324 I get an HTTP 403 error in the output, I managed to fix this by simply going to Game Settings, Security, and then enabling Enable Studio Access to API Services.

The only thing is, it’s in the security tab. Just making sure it’s safe to have that enabled because it’s in the “Security” Tab. I would also really like to know what it does exactly?

All this goes is to allow the DataStoreService to save and access data in Studio, to my knowledge. Also, I made a small update to the module, I added a feature where it checks if a leader starts folder already exists and if it does it adds it to that. And lastly, just to be sure everything works correctly and as you wanted it to right?

The loader, require(6589122875) gets a ModuleScript from the marketplace. 6589122875 is the id for the asset. When it requires the script it adds it into the game and runs the code inside it.

It works great! Thanks so much for making it.

1 Like