Any ways to improve this Checkpoint script?

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.

1 Like

Nice code.

I don’t see anything problematic there. When I’ve made checkpoint systems in the past, I’ve generally gone into a module and handled all of the data behind the scenes, but you did a great job integrating it with leaderstats here.

I don’t see any issues with your code structure or any of the functionality that I would change. There are two lines that I think are somewhat annoying to read, so if readability is a goal, then adjusting the following two lines to be a bit more readable would be nice (perhaps by sacrificing the section being only one line long).

-- LINE 1
root.CFrame = if stage.Value == 0 then checkpoints[0].CFrame else checkpointsArray[stage.Value].CFrame

-- LINE 2
leaderstats.Stage.Value = if checkpointAsNumber == leaderstats.Stage.Value + 1 then checkpointAsNumber else leaderstats.Stage.Value

Even that is a super specific thing that isn’t significant at all. For future reference, I believe this kind of post would do better under the “Code Review” section, but of course that’s also a bit nit-picky.

Good luck with your project or whatever this is for!

1 Like

Thanks for the feedback! I opted for if expressions to save lines, sacrificing a bit of readability. It handles both the assignment of data and conditionals in one line. I saw it as a cleaner approach at the time of writing. But in hindsight this system Isn’t very complex and doesn’t benefit much from saving those few lines.

And thanks for the tip of going to the code review section, I was unaware of that. Thank you!

1 Like