I’m trying to make a save system for checkpoints. the problem is the following: does anyone know how to make one spawn in a specific location as if it were a checkpoint but it is a part, I am also trying to make it so that only people can spawn with the value of the stage.
This is the script for saving and creating the value:
local DataStore = game:GetService("DataStoreService")
local Data1 = DataStore:GetDataStore("Data1")
local Data2 = DataStore:GetDataStore("Data2")
game.Players.PlayerAdded:Connect(function(player)
local folder = Instance.new("Folder", player)
folder.Name = "Stats"
local coins = Instance.new("IntValue", folder)
coins.Name = "coins"
local stage = Instance.new("IntValue", folder)
stage.Name = "stage"
local DataA1
local DataA2
local ok, errorf = pcall(function()
DataA1 = Data1:GetAsync(player.UserId)
DataA2 = Data2:GetAsync(player.UserId)
end)
if ok then
print("Data")
coins.Value = DataA1 or 100
stage.Value = DataA2 or 1
else
print("Error")
error(errorf)
end
end)
game.Players.PlayerRemoving:Connect(function(player)
local ok, errorf = pcall(function()
Data1:SetAsync(player.UserId, player.Stats.coins.Value)
Data2:SetAsync(player.UserId, player.Stats.stage.Value)
end)
if ok then
print("DataB")
else
print("ErrorB")
error(errorf)
end
end)
This is the other script that I am trying to do so that they spawn there but I don’t know how to do it when they die and it has some bugs
local savespawn1 = game.Workspace:WaitForChild("SpawnPoint1")
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
local hum = char:WaitForChild("Humanoid")
local Torso = player.Character:WaitForChild("UpperTorso")
if player.Stats.stage.Value == 1 then
Torso.CFrame = savespawn1.CFrame
end
end)
end)
rather than writing a new if statement for each checkpoint i recommend putting all the checkpoints in a folder in workspace and doing this:
local folder = game.Workspace.SpawnsFolder
--the script to determine which spawn
HumanoidRootPart:PivotTo(folder["savespawn"..tostring(player.Stats.stage.Value)])
Are you referring to saving the blocks in which I want the checkpoint to be saved to have easy access to that data and be able to change the Cframe data?
well my obby uses these to teleport player and update checkpoint
teleport using SetPrimaryPartCFrame
name checkpoints 1,2,3… or add attribute called “checkpointValue” and compare to leaderstats when touched. this way you know where to teleport to
heres my tp code unedited
player.CharacterAdded:Connect(function(character)
-- Special case (player just started game or had prestiged (resets stage))
if stage.Value == 0 then
local spawnpoint = game.Workspace.BaseParts.Other:WaitForChild("spawn") -- we could just check for object type too without checking name
if not spawnpoint then return end
repeat task.wait() until character.PrimaryPart ~= nil
character:SetPrimaryPartCFrame(spawnpoint.CFrame:ToWorldSpace(CFrame.new(0,5,0)))
return
end
-- General case
for _, checkpoint in ipairs(checkpoints:GetChildren()) do
if tostring(stage.Value) == checkpoint.Name and checkpoint:FindFirstChild("Hitbox") then
local hitbox = checkpoint:FindFirstChild("Hitbox")
if not hitbox then return end
repeat task.wait() until character.PrimaryPart ~= nil
character:SetPrimaryPartCFrame(hitbox.CFrame:ToWorldSpace(CFrame.new(0,1,-4) * CFrame.Angles(0,math.rad(-90),0)))
break
end
end
end)
yeah! touch hitbox → compare checkpointName and playerStage sizes → update stage if larger
but i would use attributes instead of model names if i was starting now. its easier to edit
simplified version of the code i use (server)
for _,checkpointDescendant in ipairs(checkpoints:GetDescendants()) do
-- Hitbox stuff
if checkpointDescendant.Name == "Hitbox" then
local hitbox = checkpointDescendant
hitbox.Touched:Connect(function(toucher)
if game:GetService("Players"):GetPlayerFromCharacter(toucher.Parent) then
local player = game:GetService("Players"):GetPlayerFromCharacter(toucher.Parent)
local leaderstats = player:WaitForChild("leaderstats")
local stage = leaderstats:WaitForChild("Stage")
local stageDataStore = DataStore2("stage 2", player) -- if youre not using DataStore2 update when player leaves instead
local coinsDataStore = DataStore2("coins", player)
if tonumber(checkpoint.Name) > stage.Value and tonumber(checkpoint.Name) - stage.Value <= 4 then -- if delta<=4 (some stages can be skipped with skill)
coinsDataStore:Increment((tonumber(checkpoint.Name) - stage.Value),0) -- 1 coin/stage
stageDataStore:Set(tonumber(checkpoint.Name))
elseif ... then -- add any cheat prevention here, like "if checkpoint is 4 higher than stage" or "if players stage is changing > 10 stages/s"
respawnModule.respawnPlayer(player)
end
end
end
end
additionally if you want you can only connect Touched if its higher than players stage in first place, and disconnect when player surpasses it so you wont be storing useless connections