Need assistance with a script

Sorry for reposting so much but I just need help with this. I’m a beginner dev and I’m trying to make it so that this script here allows the player to put their best time on the leaderboard whether they die or not. Right now it only lets the player have a leaderboard time IF THEY DO NOT DIE FROM START TO FINISH! It’s really the last thing I need to fix in the obby besides polishing it a little more! So how do I do this? LET ME KNOW IF YOU WANNA SEE THE 2 OTHER SCRIPTS THAT ARE CONNECTED TO THE LEADERBOARD, WHICH ARE THE LEADERBOARD UPDATER AND THE LOCAL TIMER GUI SCRIPT! Game’s right here if you wanna try it out by the way!

4 Likes

You can store a IntValue in the Player and increment it for every second they’re in the game, and once they finish the obby you can save that value into your datastore.

4 Likes

I’m a beginner dev and I really don’t know how to do that. Where do I add it in the script above? You mind giving an example code, because I’m clueless.

3 Likes

While I’m not sure how your leaderboard system is set up I’ll give you a piece of sample code that increments the players time by 1 every second and puts it in leaderstats

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local seconds = Instance.new("IntValue")
	seconds.Name = "Time"
	seconds.Parent = leaderstats
end)

while true do
	task.wait(1)
	
	for _, player in pairs(Players:GetPlayers()) do
		if player:FindFirstChild("leaderstats") then
			player.leaderstats.Time.Value += 1
		end
	end
end
3 Likes

Alright so the way my leaderboard works is there’s a start part that you have to touch that starts the timer and an end part that ends the timer and puts the time up on the leaderboard. The leaderboard itself works perfectly flawlessly and so does the timerGUI, but the only problem I have is the script that I posted above will not allow the player to have a time on the leaderboard when they touch the EndPart and I wish to change that so it wouldn’t matter if they died during the time trial or not. I believe the script I sent above is the main focus, but I’ll post my other 2 dealing with the leaderboard anyways! Pay attention to where the first script below ends, please! I gave you a little description before them both!

This is the leaderboard updater script that handles the leaderboard and displays the player names and time trials.


local DataStoreService = game:GetService("DataStoreService")

-- [ LOCALS ] --

local DataVer = "DataTimer" -- Data Store Name

local Store = DataStoreService:GetOrderedDataStore("LeaderBoardData2")

local RationalDigits = 3 -- How many numbers show.

-- [ FUNCTIONS ] --

function GetLBData()

	local success, pages = pcall(function()
		return Store:GetSortedAsync(true, 10)
	end)

	if success and pages then
		local data = pages:GetCurrentPage()
		local a = 0
		for _, entry in pairs(data) do
			a = a + 1
			if a == 1 then

			end
			local val = entry.value / 1000
			local Addons={}
			for t=1,RationalDigits do
				local i = t-1
				local integer,predecimal = math.modf(val*(10^i))
				local decimal = predecimal/(10^i)
				if decimal == 0 then
					Addons[t] = "0"
				end

			end
			local NewText = tostring(val)
			for i,v in pairs(Addons) do
				NewText = NewText..v
			end
			script.Parent.SurfaceGui["A" .. tostring(a)].PlrName.Text = entry.key .. ": " .. NewText
		end
	end
end

GetLBData()

while wait(60) do
	pcall(function()
		GetLBData()
	end)
end

This next one is the script that handles the touch/stop parts for timer leaderboard. It's the local script in my TImer ScreenGUI

-- [ SERVICES ] --

local RunService = game:GetService("RunService")

-- [ LOCALS ] --

local par=script.Parent

local timer=par:WaitForChild'Timer'
local timerlabel=timer:WaitForChild'Time'

local SetTime = tick()

local RationalDigits = 3 -- How many numbers is shown.

local timer_active=false
local timer_time=0

local prev

-- [ FUNCTIONS ] --

function connectplrtouch(pt,func)
	pt.Touched:Connect(function(t)
		local c=game.Players.LocalPlayer.Character
		if c and t:IsDescendantOf(c) then
			func()
		end
	end)
end

for _,d in pairs(workspace:GetDescendants()) do
	
	if d.Name=='TimerStart' then
		local name=(d:FindFirstChild'Title' and d.Title:IsA'StringValue' and d.Title.Value) or ''
		connectplrtouch(d,function()
			par.Enabled=true
			if prev~=d then
				SetTime = tick()
				prev=d
			end
			--timerlabel.Visible = true
			--timer.Visible = true
			timerlabel.TextColor3=Color3.new(1, 1, 1)
			SetTime = tick()
			timer_active=true
		end)
	end
	
	if d.Name=='TimerEnd' then
		connectplrtouch(d,function()
			timerlabel.TextColor3=Color3.new(0.172549, 1, 0.027451) -- Finish color
			if timer_active == true then
				game.ReplicatedStorage.ApplyTime:FireServer(timerlabel.Text)
			end
			timer_active=false
		end)
	end
	
end

local Accuracy = 10^RationalDigits

function TimerFunc()
	if timer_active then

		local Div1 = math.abs(tick() - SetTime)
		local CalculatedIncrement = math.round(Div1*Accuracy)/Accuracy
		local Addons={}
		for t=1,RationalDigits do
			local i = t-1
			local integer,predecimal = math.modf(CalculatedIncrement*(10^i))
			local decimal = predecimal/(10^i)
			if decimal == 0 then
				Addons[t] = "0"
			end

		end
		local NewText = tostring(CalculatedIncrement)
		for i,v in pairs(Addons) do
			NewText = NewText..v
		end
		timerlabel.Text=NewText	

	end
end

while true do
	wait(.025)
	TimerFunc()
end
4 Likes

I’m just curious, how old is this script, because its using some syntax that has been depricated.

3 Likes

I just got the script from a dude’s model last week, but the video was 1 or 2 years old mane! It was a dude named twinPlayz! The scripts work fine but I just want to make it so that whether a player dies or not they can still have a time on the leaderboard depending on if they got a top 10 time! I’ve been stressing over this for 2 weeks, but I know people have deeper problems than I do. :sunglasses:

3 Likes

I couldn’t find a reason for your code not working if the player died but I ended up just making it more efficent, removing redundant and slow code that took up memory.

--[[ Server Script ]]--
local DataStoreService = game:GetService("DataStoreService")

-- [ LOCALS ] --

local DataVer = "DataTimer" -- Data Store Name

local Store = DataStoreService:GetOrderedDataStore("LeaderBoardData2")

local RationalDigits = 3 -- How many numbers show.

-- [ FUNCTIONS ] --

function GetLBData()

	local success, pages = pcall(function()
		return Store:GetSortedAsync(true, 10)
	end)

	if success and pages then
		local topTimes = pages:GetCurrentPage()
		for rank, data in pairs(topTimes) do
			local val = data.value / 1000
			
			local decimalOffset = math.pow(10, RationalDigits)
			local RoundedTime = math.round(val*decimalOffset)/decimalOffset
			local PrettyTime = tostring(RoundedTime + (1 / (decimalOffset * 10))):sub(0, -2)
			
			script.Parent.SurfaceGui["A" .. tostring(rank)].PlrName.Text = data.key .. ": " .. PrettyTime
		end
	end
end

GetLBData()

while wait(60) do
	pcall(function()
		GetLBData()
	end)
end



--[[ Local Script ]]--
-- [ SERVICES ] --

local RunService = game:GetService("RunService")

-- [ LOCALS ] --

local Parent = script.Parent

local timer = Parent:WaitForChild('Timer')
local timerlabel = timer:WaitForChild('Time')

local SetTime = tick()

local RationalDigits = 3 -- How many numbers is shown.

local timer_active = false
local timer_time = 0

local prev

-- [ FUNCTIONS ] --

function OnPlayerTouched(part,func)
	part.Touched:Connect(function(touched)
		local character = game.Players.LocalPlayer.Character
		if character and touched:IsDescendantOf(character) then
			func()
		end
	end)
end

for _,descendant in pairs(workspace:GetDescendants()) do

	if descendant.Name == 'TimerStart' then
		OnPlayerTouched(descendant,function()
			Parent.Enabled = true
			if prev ~= descendant then
				SetTime = tick()
				prev = descendant
			end
			timerlabel.TextColor3 = Color3.new(1, 1, 1)
			SetTime = tick()
			timer_active = true
		end)
	end

	if descendant.Name == 'TimerEnd' then
		OnPlayerTouched(descendant,function()
			timerlabel.TextColor3=Color3.new(0.172549, 1, 0.027451) -- Finish color
			if timer_active == true then
				game.ReplicatedStorage.ApplyTime:FireServer(timerlabel.Text)
			end
			timer_active=false
		end)
	end

end


function TimerFunc()
	if timer_active then
		local timePassed = math.abs(tick() - SetTime)
		
		local decimalOffset = math.pow(10, RationalDigits)
		local RoundedTime = math.round(timePassed*decimalOffset)/decimalOffset
		local PrettyTime = tostring(RoundedTime + (1 / (decimalOffset * 10))):sub(0, -2)
		
		timerlabel.Text= PrettyTime	
	end
end

while true do
	wait(.025)
	TimerFunc()
end
2 Likes

Thank you for the help but I noticed that you removed the anticheat kicker in the script, so I’ll have to put that back! At the top of the server script you sent back, the dude said, “Only saves time when player fully completes course without dying.” Also, I don’t know if you missed it or not but here’s the script that’s inside of the leaderboard part itself!

-- [ SERVICES ] --

local DataStoreService = game:GetService("DataStoreService")

-- [ LOCALS ] --

local DataVer = "DataTimer" -- Data Store Name

local Store = DataStoreService:GetOrderedDataStore("LeaderBoardData2")

local RationalDigits = 3 -- How many numbers show.

-- [ FUNCTIONS ] --

function GetLBData()

	local success, pages = pcall(function()
		return Store:GetSortedAsync(true, 10)
	end)

	if success and pages then
		local data = pages:GetCurrentPage()
		local a = 0
		for _, entry in pairs(data) do
			a = a + 1
			if a == 1 then

			end
			local val = entry.value / 1000
			local Addons={}
			for t=1,RationalDigits do
				local i = t-1
				local integer,predecimal = math.modf(val*(10^i))
				local decimal = predecimal/(10^i)
				if decimal == 0 then
					Addons[t] = "0"
				end

			end
			local NewText = tostring(val)
			for i,v in pairs(Addons) do
				NewText = NewText..v
			end
			script.Parent.SurfaceGui["A" .. tostring(a)].PlrName.Text = entry.key .. ": " .. NewText
		end
	end
end

GetLBData()

while wait(60) do
	pcall(function()
		GetLBData()
	end)
end
1 Like

Yeah the leaderboard script is the same as this one, without all of the unneeded code

--[[ Server Script ]]--
local DataStoreService = game:GetService("DataStoreService")

-- [ LOCALS ] --

local DataVer = "DataTimer" -- Data Store Name

local Store = DataStoreService:GetOrderedDataStore("LeaderBoardData2")

local RationalDigits = 3 -- How many numbers show.

-- [ FUNCTIONS ] --

function GetLBData()

	local success, pages = pcall(function()
		return Store:GetSortedAsync(true, 10)
	end)

	if success and pages then
		local topTimes = pages:GetCurrentPage()
		for rank, data in pairs(topTimes) do
			local val = data.value / 1000
			
			local decimalOffset = math.pow(10, RationalDigits)
			local RoundedTime = math.round(val*decimalOffset)/decimalOffset
			local PrettyTime = tostring(RoundedTime + (1 / (decimalOffset * 10))):sub(0, -2)
			
			script.Parent.SurfaceGui["A" .. tostring(rank)].PlrName.Text = data.key .. ": " .. PrettyTime
		end
	end
end

GetLBData()

while wait(60) do
	pcall(function()
		GetLBData()
	end)
end



2 Likes

Oh yeah that’s the script inside the Leaderboard Part itself and thank you for tidying it up! But this is the serverscriptservice one I’m having trouble with; I made the post on it. Its alright though I might’ve confused you with how everything’s set up but the one you sent isn’t the one I’m having the problem with in serverscriptservice. This is :sunglasses:


-- [ SERVICES ] --

local DataStoreService = game:GetService("DataStoreService")

-- [ LOCALS ] --

local DataVer = "[DataTimer]" -- Data Store Name
local Store = DataStoreService:GetOrderedDataStore("LeaderBoardData2")

-- [ FUNCTIONS ] --

_G.ForceSet = function(plrName, newTime)
	local num = tonumber(newTime)

	num = num * 1000
	Store:SetAsync(plrName, num)
end

game.ReplicatedStorage.ApplyTime.OnServerEvent:Connect(function(plr, newTime) -- On Event
	
	local num = tonumber(newTime)
	local oldData = Store:GetAsync(plr.UserId)
	
	if oldData then
		oldData = oldData / 1000
	else
		oldData = 1000
	end
	
	---- ANTI CHEAT (needs fixing)
	if num < oldData then
		if num <= 900.00 then
			plr:Kick("No cheating bucko!")
		else
			num = num * 1000
			Store:SetAsync(plr.UserId, num)
		end
	end
	
end)
2 Likes

OKAY SOMETHING FUNNY JUST HAPPENED! Thank you for helpingf, it works even when I reset and die BUT IT SHOWS MY ID INSTEAD OF MY NAME :rofl:

1 Like

Just a heads up: I think you missed a few:

3 Likes

Waddup Ant, nice to see you stop by man! I believe the problem is finally fixed BUT I think I have to do Store:SetAsync(plr.Username) instead of SetAsync(plr.UserId)

1 Like

Yeah, but I didn’t want to touch that stuff just in case I messed anything up, since I couldn’t test the code…

2 Likes

Also nah that’s (60) thing refreshes the leaderboard and the (0.25) thing is for the timer

I believe so. However, I think it is SetAsync(plr.Name) to be precise. It would replace something here:

However, you may have to manually remove the old key.

1 Like

Gotcha! I found out how to use the datastore editor but the keys for the leaderboard werent there if that makes sense! I’ll find it! :sunglasses: :+1:t4:

1 Like

Is this line correct now? Or do i just leave out the “num”

Store:SetAsync(plr.name, num)

Yes, you leave in the num. But make sure name is capitalized!

1 Like