Gave my attempt at writing a modern obby checkpoint script. Works as intended, but I’m curious if there are any other changes I can make to improve, optimize and modernize this code.
It utilizes type checking, if expressions/ternary expressions, and generalized iteration(no need for next, pairs or ipairs). Are there any other features I could use to improve this code? Anything that should be changed or removed? Or should this current system be scrapped entirely in favor of a more optimal approach?
I’d love to hear your thoughts!
local checkpoints: Folder = workspace.Checkpoints
local checkpointsArray: {BasePart} = checkpoints:GetChildren()
game.Players.PlayerAdded:Connect(function(player: Player)
local leaderstats: Folder = player:WaitForChild("leaderstats")
local stage: IntValue = leaderstats:WaitForChild("Stage")
player.CharacterAdded:Connect(function(character: Model)
local root = character:WaitForChild("HumanoidRootPart")
--[[
Can't access the "0" part using an array since arrays don't begin at 0.
I used a ternary to check if the stage value is 0.
If it is, manually set the character CFrame to the part named "0" in the checkpoints folder.
Else, just use the array and index normally.
--]]
root.CFrame = if stage.Value == 0 then checkpoints[0].CFrame else checkpointsArray[stage.Value].CFrame
end)
end)
for _, checkpoint in checkpointsArray do
local checkpointAsNumber = tonumber(checkpoint.Name)
checkpoint.Touched:Connect(function(hit: BasePart)
local player: Player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
local leaderstats: Folder = player:WaitForChild("leaderstats")
if leaderstats then
leaderstats.Stage.Value = if checkpointAsNumber == leaderstats.Stage.Value + 1 then checkpointAsNumber else leaderstats.Stage.Value
end
end
end)
end
The only setup is a folder in the workspace named “Checkpoints” which simply contains BaseParts, each with a unique name in the form of a number, ranging from 0-10. The name of the BaseParts is how I determine the stage.