How to make a system where you can go back and forth to each stage but not to other stages you haven't completed?

I am trying to create a system like MasterDaniel’s Masters Difficulty Chart Obby where the player can click one of the buttons on the GUIs and it takes you back to one of the previous stages the player has completed. There is also another button that can make the player go up one stage all the way up to the stage the player is currently in (example). I made some scripts after having an idea and tried to implement it. Sure enough, my ideas never work. The script keeps on bugging and it doesn’t work as I want it to. First of all, when I click the button to go to the previous stages, my leaderboard stats are able to go to the negative values and I don’t want that to happen. I want the lowest leaderstat to be 0. Second of all, when I click the button to go to a previous stage, the leaderboard value goes down twice instead of going down once. Finally, Whenever I press the button to go back to the previous stages and it resets my character, it doesn’t teleport me to the checkpoint that I was supposed to go to. My checkpoint scripts work so I believe something is wrong with my local script shown below (Examples of each problem here). I have tried to do a in pairs loop but each problem still occurs. I haven’t scripted the button where you can go up one stage until you reach the stage you are currently in but I plan to script that once I find a solution the the button that I am currently scripting. My code is being shown below and I thank you in advance.

local Button = script.Parent
local Checkpoints = game.Workspace.Checkpoints:GetChildren()
Button.MouseButton1Click:Connect(function()
		local plr = game.Players.LocalPlayer
		local char = plr.Character
		for i, v in pairs(Checkpoints) do
			if v.BrickColor == BrickColor.new("Lime green") then
				plr.leaderstats.Stage.Value = plr.leaderstats.Stage.Value - 1
				wait(0.3)
				char.Head:Remove()	
		end
	end
end)
2 Likes

Just have a current stage and completed stages values:

local currentStage = -- The stage the player is on at the moment
local completedStage = -- The last stage the player has completed

Button.MouseButton1Click:Connect(function() -- Go forward a stage
    if currentStage ~= "LOWEST_STAGE_HERE" then -- Checking if the player isn't on the first stageg
        currentStage -= 1 -- Decrease their stage
        -- teleport to that stage
    end
end)

Button.MouseButton1Click:Connect(function() -- Go backward a stage
    if currentStage ~= completedStage then -- Checking if the player is on the "completedStage"
        currentStage += 1 -- Increase their stage
        -- teleport to that stage
    end
end)
1 Like

Is the Current Stage like the plr.leaderstats.Stage.Value? I also do not know how to define the stage the player has last completed

First, you don’t check if the current stage is above the lowest stage.
Also, you can’t change values on the client, it just looks like you can.
This script is also easily hackable, you want to do most things on the server because hackers can change local scripts. Let me write a solution for you in just a second.

--- Client
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage:WaitForChild("ChangeStage")
local button = script.Parent

button.MouseButton1Click:Connect(function()
	Event:FireServer("Backwards")
end)

-- Server
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Event = Instance.new("RemoteEvent")
Event.Name = "ChangeStage"
Event.Parent = ReplicatedStorage

Players.PlayerAdded:Connect(function(plr)
	local CurrStage = Instance.new("IntValue")
	CurrStage.Name = "CurrStage"
	CurrStage.Value = plr:WaitForChild("leaderstats"):WaitForChild("Stage").Value
	CurrStage.Parent = plr
	plr.Character.Humanoid.Died:Connect(function()
		CurrStage.Value = plr:WaitForChild("leaderstats"):WaitForChild("Stage").Value
	end)
end)

Event.OnServerEvent:Connect(function(plr,type)
	if type == "Backwards" then
		plr.CurrStage.Value -= 1
		plr.Character:SetPrimaryPartCFrame(workspace:WaitForChild("Checkpoints")[plr.CurrStage.Value])
	end
end)

1 Like

I tried your script out and it showed an error on this line saying "’-2 is not a valid member of Folder “Workspace.Checkpoints’” Each checkpoint (I currently have 31 checkpoints) are part of the folder called Checkpoints if you didn’t know.

Wait, I’m sorry. I didn’t realize that I was still in the negative stage value. Let me reset my stage stat again.

This script assumes your checkpoints are called “1”, “2” and so on.

Hmm… I think there is something wrong with this line of code here. When I tested the script out again, it said "-1 is not a valid member of Folder “Workspace.Checkpoints.” When I clicked the button again, the error said "-2 is not a valid member of Folder “Workspace.Checkpoints.” When I clicked the button once more, it said "-3 is not a valid member of Folder “Workspace.Checkpoints,” and it kept on stacking.

What is your firsts stage name? Is it 0 or 1?

if type == "Backwards" then
   if plr.CurrStage.Value >= 1 then -- This assumes the stage stage is 0, change the number to 2 if your first stage is 1
      plr.CurrStage.Value -= 1
      plr.Character:SetPrimaryPartCFrame(workspace:WaitForChild("Checkpoints")[plr.CurrStage.Value])
   end
end

My checkpoints are named Checkpoint1, Checkpoint2, Checkpoint3, and all the way to Checkpoint31. Sorry for not being specific.

Ok, let me fix the code. Just a second.

if type == "Backwards" then
if plr.CurrStage.Value >= 2 then 
      plr.CurrStage.Value -= 1
      plr.Character:SetPrimaryPartCFrame(workspace:WaitForChild("Checkpoints")["Checkpoint"+tostring(plr.CurrStage.Value)])
   end
end

I don’t see any error with the most recent script you have sent me but there is an error here that says “ServerScriptService.ChangeStage:10: attempt to index nil with ‘Humanoid’” I tried to fix this with this code below which has no errors but the script does not do anything.

Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		local CurrStage = Instance.new("IntValue")
		CurrStage.Name = "CurrStage"
		CurrStage.Value = plr:WaitForChild("leaderstats"):WaitForChild("Stage").Value
		CurrStage.Parent = plr
		char.Humanoid.Died:Connect(function()
			CurrStage.Value = plr:WaitForChild("leaderstats"):WaitForChild("Stage").Value
		end)
	end)
end)

Then use this.

 local char = player.Character
if not character or not character.Parent then
 character = player.CharacterAdded:wait()
end

Your code did work technically because there were no errors, but when I clicked the button it wouldn’t decrease my stage value. (video-example)

Oh, let me see if i can fix that.

Thank you so much. I have been trying to make one of these systems for a week now and I couldn’t get help from here until yesterday when I got membership role

Does the console say anything?