Help with battlepass system

i am trying to make a battlepass system that rewards you every level up the issue is, when the player finishes a certain quest he levels up twice insted of one time i will leave the video down below

battlepass.wmv (5.3 MB)
that is what happens when the player finishes 1 quest

server script:

local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("testing1.0.5")

local missions = {
	"Play for 10 minutes",
	"Walk 20000 meters",
	"Kill a total of 15000 beasts",
}

local tiers = 3

--Data saving function
function saveData(plr)

	local tier = plr.Tier.Value
	local lastMission = plr.LastMission.Value
	local currentMissions = {}

	for i, mission in pairs(plr.Missions:GetChildren()) do

		currentMissions[mission.Name] = mission.Value
		if mission:FindFirstChild("Completed") then
			currentMissions[mission.Name] = -1
		end
	end

	local bpData = {["CurrentMissions"] = currentMissions, ["LastMission"] = lastMission, ["Tier"] = tier}

	ds:SetAsync(plr.UserId .. "Battlepass", bpData)
end

game.Players.PlayerAdded:Connect(function(plr)

	--Character related missions
	plr.CharacterAdded:Connect(function(char)

		local missionsFolder = plr:WaitForChild("Missions")

		for i, mission in pairs(missionsFolder:GetChildren()) do

			if not mission:FindFirstChild("Completed") then
				if mission.Name == "Walk 20000 meters" then --Walk for 500 studs

					spawn(function()
						local lastPosition = char.HumanoidRootPart.Position * Vector3.new(1, 0, 1)

						while wait() do	
							if not mission:FindFirstChild("Completed") then
								local currentPos = char.HumanoidRootPart.Position * Vector3.new(1, 0, 1)

								mission.Value += (lastPosition - currentPos).Magnitude

								lastPosition = currentPos

								if mission.Value >= 20000 then

									local complete = Instance.new("StringValue", mission)
									complete.Name = "Completed"
									plr.Tier.Value += 1
									break
								end
							end
						end
					end)

				elseif mission.Name == "Kill a total of 15000 beasts" then --Stand still for 10 seconds

					spawn(function()

						while wait() do
							if plr.leaderstats.Kills.Value >= 15000 then
								mission.Value = 15000
								break
							end
							mission.Value = plr.leaderstats.Kills.Value
						end
						if mission.Value >= 15000 then
							local complete = Instance.new("StringValue", mission)
							complete.Name = "Completed"
							plr.Tier.Value += 1
						end
					end)
				end
			end
		end
	end)

	--Battlepass data
	local bpData = ds:GetAsync(plr.UserId .. "Battlepass") or {["CurrentMissions"] = nil, ["LastMission"] = 0, ["Tier"] = 0}

	local currentMissions = bpData["CurrentMissions"]

	local tier = bpData["Tier"]

	local lastMission = bpData["LastMission"]

	if os.time() - lastMission >= 24*60*60 then--24*60*60 then --Reset missions after 24 hours

		lastMission = os.time()

		currentMissions = {}

		for i = 1, math.clamp(tiers - tier, 0, 3) do --Make sure the user doesn't complete more tiers than there are

			local mission
			repeat
				mission = missions[math.random(#missions)]
			until not currentMissions[mission]

			currentMissions[mission] = 0
		end
	end

	local lastValue = Instance.new("IntValue", plr)
	lastValue.Name = "LastMission"
	lastValue.Value = lastMission

	local tierValue = Instance.new("IntValue", plr) --Current tier
	tierValue.Name = "Tier"
	tierValue.Value = tier

	tierValue:GetPropertyChangedSignal("Value"):Connect(function() --Reward for tiers
		if tierValue.Value == 1 then
			local clone = game.ServerStorage:WaitForChild("Tools"):WaitForChild("Beast Head"):Clone()
			clone.Parent = plr.Backpack
		end
	end)

	local missionsFolder = Instance.new("Folder", plr) --Missions stored in here
	missionsFolder.Name = "Missions"

	for currentMission, progress in pairs(currentMissions) do

		local missionValue = Instance.new("NumberValue", missionsFolder)
		missionValue.Name = currentMission

		missionValue.Value = progress

		if progress >= 0 then
			--Play for 10 minutes
			if currentMission == "Play for 10 minutes" then
				spawn(function()
					local timeJoined = os.time()

					while wait() do

						local timePlayed = progress + math.floor((os.time() - timeJoined)/60)

						if plr and timePlayed < 10 then

							plr.Missions["Play for 10 minutes"].Value = timePlayed

						else
							plr.Missions["Play for 10 minutes"].Value = 10
							break
						end
					end

					if plr then

						tierValue += 1
						local complete = Instance.new("StringValue", missionValue)
						complete.Name = "Completed"
					end
				end)
			end

		else
			local complete = Instance.new("StringValue", missionValue)
			complete.Name = "Completed"
			missionValue.Value = string.gsub(currentMission, "%D", "")
		end
	end
end)

--Save data using function
game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	for i, plr in pairs(game.Players:GetPlayers()) do
		saveData(plr)
	end
end)

local script:

--Open and close GUI
local open = false

script.Parent.Position = UDim2.new(0.319, 0,0.975, 0)

script.Parent.MouseButton1Click:Connect(function()

	open = not open

	if open then
		script.Parent:TweenPosition(UDim2.new(0.319, 0,0.975, 0), "InOut", "Quint", 0.5)
	else
		script.Parent:TweenPosition(UDim2.new(0.319, 0,0.686, 0), "InOut", "Quint", 0.5)
	end
end)

--Tiers UI
local maxTiers = 3
local tier = game.Players.LocalPlayer:WaitForChild("Tier")
script.Parent.BattlepassFrame.TierNumber.Text = "LEVEL: " .. tier.Value

for i = 1, maxTiers do --Set up scrolling frame with tier rewards

	local newTier = script.RewardFrame:Clone()
	newTier.Name = i
	newTier.TierNumber.Text = "LEVEL: " .. i
	if i == 1 then
		newTier.RewardName.Text = "BEAST HEAD"
		newTier.RewardImage.Image = "rbxassetid://90177088"
	elseif i == 2 then
		newTier.RewardName.Text = "AK-47"
		newTier.RewardImage.Image = "rbxassetid://11127408662"
	elseif i == 3 then
		newTier.RewardName.Text = "REVOLVER"
		newTier.RewardImage.Image = "rbxassetid://7587568389"
	end

	if i <= tier.Value then

		newTier.NotClaimedImage:Destroy()
	end

	newTier.Parent = script.Parent.BattlepassFrame.RewardsScroller

	script.Parent.BattlepassFrame.RewardsScroller.CanvasSize = UDim2.new(0, script.Parent.BattlepassFrame.RewardsScroller.UIListLayout.AbsoluteContentSize.X, 0, 0)
end

tier:GetPropertyChangedSignal("Value"):Connect(function() --Update UI when tier changes

	script.Parent.BattlepassFrame.TierNumber.Text = "LEVEL: " .. tier.Value

	for i, tierReward in pairs(script.Parent.BattlepassFrame.RewardsScroller:GetChildren()) do
		if tonumber(tierReward.Name) and tonumber(tierReward.Name) <= tier.Value then

			if tierReward:FindFirstChild("NotClaimedImage") then tierReward.NotClaimedImage:Destroy() end
		end
	end
end)

--Missions UI
local missionsFolder = game.Players.LocalPlayer:WaitForChild("Missions")

for i, mission in pairs(missionsFolder:GetChildren()) do

	local missionAmount = string.gsub(mission.Name, "%D", "")

	local missionFrame = script.Parent.BattlepassFrame.MissionsFrame["Mission" .. i]
	missionFrame.Task.Text = mission.Name
	missionFrame.ProgressBarBG.Progress.Text = math.floor(mission.Value) .. "/" .. missionAmount

	missionFrame.ProgressBarBG.Bar.Size = UDim2.new(math.clamp(mission.Value / missionAmount, 0, 1), 0, 1, 0)

	mission:GetPropertyChangedSignal("Value"):Connect(function()

		missionFrame.ProgressBarBG.Progress.Text = math.floor(mission.Value) .. "/" .. missionAmount

		missionFrame.ProgressBarBG.Bar.Size = UDim2.new(math.clamp(mission.Value / missionAmount, 0, 1), 0, 1, 0)
	end)
end

if #missionsFolder:GetChildren() < 1 then --Make sure the right amount of missions is shown
	script.Parent.BattlepassFrame.MissionsFrame:ClearAllChildren()
elseif #missionsFolder:GetChildren() < 2 then
	script.Parent.BattlepassFrame.MissionsFrame.Mission2:Destroy()
	script.Parent.BattlepassFrame.MissionsFrame.Mission3:Destroy()
elseif #missionsFolder:GetChildren() < 3 then
	script.Parent.BattlepassFrame.MissionsFrame.Mission3:Destroy()
end

Can u give the script btw so we can analyze. Thanks

1 Like

plr.Tier.Value += 1 this signifying that it could also be equal to one. That might confuse the computer. I would try Local LevelUp = plr.Tier.Value + 1 Then you can easily refer back to leveling up a tier by stating in code LevelUp (note: this script wont work until you refer back to it “LevelUp” on the script. There are many ways to do this but I would probably make it when integer has reached this number LevelUp (thats not how u code it btw)

1 Like

ok, i will try it out thanks for the reply!

1 Like

If that doesn’t work do the same thing but Local LevelUp = plr.Tier.Value += 1 but that would prob wouldn’t work but worth a shot (|do this after you do everything states in the last comment and it doesn’t work)

neither of those solutions seemed to have worked :confused:

EDIT: yeah i did refer

You made sure you referred to LevelUp later on?

1 Like

Can you post the updated script so I can see how u did? (Do how the script looked like when it was Local LevelUp = plr.Tier.Value + 1

sorry for not replying but i found the solution i forgot to check if it was completed

Glad I could help!! Keep in future reference that if you need to fix an issue like that its good to define it first! Have a nice day!

Quick question tho what was the solution. Was it what I asked?

sorry for not replying again im kinda busy this time of hour :confused: here is the correct script and no, it sadly wasnt what you asked

local dss = game:GetService("DataStoreService")
local ds = dss:GetDataStore("testing1.1.1")

local missions = {
	"Play for 10 minutes",
	"Walk 20000 meters",
	"Kill a total of 15000 beasts",
}

local tiers = 3
local times = 0

--Data saving function
function saveData(plr)

	local tier = plr.Tier.Value
	local lastMission = plr.LastMission.Value
	local currentMissions = {}

	for i, mission in pairs(plr.Missions:GetChildren()) do

		currentMissions[mission.Name] = mission.Value
		if mission:FindFirstChild("Completed") then
			currentMissions[mission.Name] = -1
		end
	end

	local bpData = {["CurrentMissions"] = currentMissions, ["LastMission"] = lastMission, ["Tier"] = tier}

	ds:SetAsync(plr.UserId .. "Battlepass", bpData)
end

game.Players.PlayerAdded:Connect(function(plr)

	--Character related missions
	plr.CharacterAdded:Connect(function(char)

		local missionsFolder = plr:WaitForChild("Missions")

		for i, mission in pairs(missionsFolder:GetChildren()) do

			if not mission:FindFirstChild("Completed") then
				if mission.Name == "Walk 20000 meters" then --Walk for 500 studs

					spawn(function()
						local lastPosition = char.HumanoidRootPart.Position * Vector3.new(1, 0, 1)

						while wait() do	
							if not mission:FindFirstChild("Completed") then
								local currentPos = char.HumanoidRootPart.Position * Vector3.new(1, 0, 1)

								mission.Value += (lastPosition - currentPos).Magnitude

								lastPosition = currentPos

								if mission.Value >= 20000 then

									local complete = Instance.new("StringValue", mission)
									complete.Name = "Completed"
									--plr.Tier.Value += 1
									break
								end
							end
						end
					end)

				elseif mission.Name == "Kill a total of 15000 beasts" then --Stand still for 10 seconds

					spawn(function()

						while task.wait() do
							if plr.leaderstats.Kills.Value >= 15000 and not mission:FindFirstChild("Completed") then
								mission.Value = 15000
								if mission.Value == 15000 then
									local complete = Instance.new("StringValue", mission)
									complete.Name = "Completed"
									plr.Tier.Value += 1
									times += 1 
									print(times)
									break
								end
							end
							mission.Value = plr.leaderstats.Kills.Value
						end
					end)
				end
			end
		end
	end)

	--Battlepass data
	local bpData = ds:GetAsync(plr.UserId .. "Battlepass") or {["CurrentMissions"] = nil, ["LastMission"] = 0, ["Tier"] = 0}

	local currentMissions = bpData["CurrentMissions"]

	local tier = bpData["Tier"]

	local lastMission = bpData["LastMission"]

	if os.time() - lastMission >= 24*60*60 then--24*60*60 then --Reset missions after 24 hours

		lastMission = os.time()

		currentMissions = {}

		for i = 1, math.clamp(tiers - tier, 0, 3) do --Make sure the user doesn't complete more tiers than there are

			local mission
			repeat
				mission = missions[math.random(#missions)]
			until not currentMissions[mission]

			currentMissions[mission] = 0
		end
	end

	local lastValue = Instance.new("IntValue", plr)
	lastValue.Name = "LastMission"
	lastValue.Value = lastMission

	local tierValue = Instance.new("IntValue", plr) --Current tier
	tierValue.Name = "Tier"
	tierValue.Value = tier

	tierValue:GetPropertyChangedSignal("Value"):Connect(function() --Reward for tiers
		if tierValue.Value == 1 then
			local clone = game.ServerStorage:WaitForChild("Tools"):WaitForChild("Beast Head"):Clone()
			clone.Parent = plr.Backpack
		elseif tierValue.Value == 2 then
			-- reward ak47
		elseif tierValue.Value == 3 then
			-- reward elderwood revolver
		end
	end)

	local missionsFolder = Instance.new("Folder", plr) --Missions stored in here
	missionsFolder.Name = "Missions"

	for currentMission, progress in pairs(currentMissions) do

		local missionValue = Instance.new("NumberValue", missionsFolder)
		missionValue.Name = currentMission

		missionValue.Value = progress

		if progress >= 0 then
			--Play for 10 minutes
			if currentMission == "Play for 10 minutes" then
				spawn(function()
					local timeJoined = os.time()

					while wait() do

						local timePlayed = progress + math.floor((os.time() - timeJoined)/60)

						if plr and timePlayed < 10 then

							plr.Missions["Play for 10 minutes"].Value = timePlayed

						else
							plr.Missions["Play for 10 minutes"].Value = 10
							break
						end
					end

					if plr then

						tierValue += 1
						local complete = Instance.new("StringValue", missionValue)
						complete.Name = "Completed"
					end
				end)
			end

		else
			local complete = Instance.new("StringValue", missionValue)
			complete.Name = "Completed"
			missionValue.Value = string.gsub(currentMission, "%D", "")
		end
	end
end)

--Save data using function
game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	for i, plr in pairs(game.Players:GetPlayers()) do
		saveData(plr)
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.