Need some assistance with script(s) on this thread!

Mane I’ve been posting this for a while, can anybody help with this thread? I’m a beginner and I’ve been raging at this for weeks, but I know someone out there probably knows the solution. :skull: Need a little assistance with a script!

I am not 100% certain the script will function as-is, please do tell if it does not work as intended!

-- // NOTE: The type names after variables come from Luau type checking!
-- // If you want to learn more about that, this page holds a lot of information: https://create.roblox.com/docs/luau

--[[
	This script handles the touch/stop plates for timer leaderboard.
--]]

-- [ SERVICES ] --

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

-- [ LOCALS ] --

local LocalPlayer = Players.LocalPlayer
local CurrentCharacter: Model?

local Parent = script.Parent
local Timer = Parent:WaitForChild("Timer")
local TimerLabel = Timer:WaitForChild("Time")

local PreviousPart: BasePart?
local IsTimerActive = false
local CountingFrom = 0

-- [ FUNCTIONS ] --

local function StopTimer()
	if not IsTimerActive then
		return
	end
	
	IsTimerActive = false

	-- // This is VERY insecure! Exploiters can and will spoof this data to get advantage
	-- // over other players on the leaderboard. Consider using a server-sided check
	-- // in the future.
	ReplicatedStorage.ApplyTime:FireServer(tick() - CountingFrom)
end

local function OnCharacterAdded(Character: Model)
	CurrentCharacter = Character
	
	local Humanoid = Character:WaitForChild("Humanoid", 10):: Humanoid
	if not Humanoid then
		return
	end

	Humanoid.Died:Once(StopTimer)
end

local function OnPlayerTouched(Part: BasePart, Function: () -> ...any)
	Part.Touched:Connect(function(Hit: BasePart)
		if CurrentCharacter and Hit:IsDescendantOf(CurrentCharacter) then
			Function()
		end
	end)
end

for _, Descendant: Instance in workspace:GetDescendants() do
	if not Descendant:IsA("BasePart") then
		continue
	end
	
	if Descendant.Name == "TimerStart" then
		local Title = Descendant:FindFirstChild("Title"):: StringValue
		local Name = if Title and Title:IsA("StringValue")
			then Title.Value
			else ""
		OnPlayerTouched(Descendant, function()
			Parent.Enabled = true
			if PreviousPart ~= Descendant then
				CountingFrom = tick()
				PreviousPart = Descendant
			end
			
			TimerLabel.TextColor3 = Color3.new(1, 1, 1)
			IsTimerActive = true
		end)
	elseif Descendant.Name == "TimerEnd" then
		OnPlayerTouched(Descendant, function()
			if not IsTimerActive then
				return
			end
			
			TimerLabel.TextColor3 = Color3.new(0.172, 1, 0.027)
			StopTimer()
			
			PreviousPart = nil
			IsTimerActive = false
		end)
	end
end

local function UpdateTimer()
	if not IsTimerActive then
		return
	end
	
	local TimePassed = tick() - CountingFrom
	TimerLabel.Text = string.format("%.3f", TimePassed)
end

-- // Initiate the CurrentCharacter variable & death check
if LocalPlayer.Character then
	task.spawn(OnCharacterAdded, LocalPlayer.Character)
end

LocalPlayer.CharacterAdded:Connect(OnCharacterAdded)

while task.wait(0.025) do
	UpdateTimer()
end
1 Like

Will do! I’ll get back with you shortly and thank you for taking the time to stop by and help!:sunglasses::+1:t4:

1 Like

Hey wawa Im back! So there seems to be 3 odd things goin on down below! Also by all means you’ve done nothing wrong!

These are a few errors that popped up since using the script. It looks like the script is interfering with the script in serverscriptservice called “LeaderBoardTimerScript”:

It wont let me upload the 2 other clips I wanted to show from my phone since “the file is too large” so I’m fine with typing out whats happening! When I die it stops the timer completely and after I go back in the timer starter it resumes the timer at the correct amount of seconds. What I mean is if the timer stops when I die at 20 seconds, if I walk into the timer starter 30 seconds later it’ll resume at 50! Also it kicks you from the game on death! :sunglasses:

I see, could you explain once again how you want it to work? Do you want the timer to continue going even upon death or something? I am a bit uncertain as to what the expected result is.

1 Like

All good mane, I just want it to do the opposite of what it says in the 2nd sentence at the very top of this script here. I want the script to let the player have a time on the leaderboard even if they die from start to finish because right now it only lets the player get a time if they survive from point A(TimerStart) to point B(TimerEnd). Pay attention to the 2nd sentence at the top in the brackets. “Only saves time when player fully completes course without dying” i want to make it so that they can save their time even if they die! :sunglasses:

--[[
    This script will apply the leaderboard time, and check if a player has finished or completed the obby.
    Only saves time when player fully completes course without dying.
--]]

-- [ SERVICES ] --

local DataStoreService = game:GetService("DataStoreService")

-- [ LOCALS ] --

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

-- [ 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, please!")
        else
            num = num * 1000
            Store:SetAsync(plr.UserId, num)
        end
    end
    
end)

Basically so… death qualifies as a completion and gets logged on the leaderboard? So like, if you die - the time since the start up until you die is logged as your time?

If that is the case, this script should work…? It tells the server the time upon death too, now should also properly reset the variables. If you do make it like that, however, I’m not too certain how would you implement an anti-cheat…

-- // NOTE: The type names after variables come from Luau type checking!
-- // If you want to learn more about that, this page holds a lot of information: https://create.roblox.com/docs/luau

--[[
	This script handles the touch/stop plates for timer leaderboard.
--]]

-- [ SERVICES ] --

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

-- [ LOCALS ] --

local LocalPlayer = Players.LocalPlayer
local CurrentCharacter: Model?

local Parent = script.Parent
local Timer = Parent:WaitForChild("Timer")
local TimerLabel = Timer:WaitForChild("Time")

local PreviousPart: BasePart?
local IsTimerActive = false
local CountingFrom = 0

-- [ FUNCTIONS ] --

local function StopTimer()
	if not IsTimerActive then
		return
	end
	
	IsTimerActive = false
	PreviousPart = nil
	
	-- // This is VERY insecure! Exploiters can and will spoof this data to get advantage
	-- // over other players on the leaderboard. Consider using a server-sided check
	-- // in the future.
	ReplicatedStorage.ApplyTime:FireServer(tick() - CountingFrom)
	
	CountingFrom = 0
end

local function OnCharacterAdded(Character: Model)
	CurrentCharacter = Character
	
	local Humanoid = Character:WaitForChild("Humanoid", 10):: Humanoid
	if not Humanoid then
		return
	end

	Humanoid.Died:Once(StopTimer)
end

local function OnPlayerTouched(Part: BasePart, Function: () -> ...any)
	Part.Touched:Connect(function(Hit: BasePart)
		if CurrentCharacter and Hit:IsDescendantOf(CurrentCharacter) then
			Function()
		end
	end)
end

for _, Descendant: Instance in workspace:GetDescendants() do
	if not Descendant:IsA("BasePart") then
		continue
	end
	
	if Descendant.Name == "TimerStart" then
		local Title = Descendant:FindFirstChild("Title"):: StringValue
		local Name = if Title and Title:IsA("StringValue")
			then Title.Value
			else ""
		OnPlayerTouched(Descendant, function()
			Parent.Enabled = true
			if PreviousPart ~= Descendant then
				CountingFrom = tick()
				PreviousPart = Descendant
			end
			
			TimerLabel.TextColor3 = Color3.new(1, 1, 1)
			IsTimerActive = true
		end)
	elseif Descendant.Name == "TimerEnd" then
		OnPlayerTouched(Descendant, function()
			if not IsTimerActive then
				return
			end
			
			TimerLabel.TextColor3 = Color3.new(0.172, 1, 0.027)
			StopTimer()
		end)
	end
end

local function UpdateTimer()
	if not IsTimerActive then
		return
	end
	
	local TimePassed = tick() - CountingFrom
	TimerLabel.Text = string.format("%.3f", TimePassed)
end

-- // Initiate the CurrentCharacter variable & death check
if LocalPlayer.Character then
	task.spawn(OnCharacterAdded, LocalPlayer.Character)
end

LocalPlayer.CharacterAdded:Connect(OnCharacterAdded)

while task.wait(0.025) do
	UpdateTimer()
end
1 Like

Hey do I put this in the local script for the timerGUI or the serverscriptservice script I just sent above your comment? I’m guessing Local

That’s the client script for the GUI, so therefore it’s supposed to be a LocalScript.

1 Like

Alrighty, same error popped up for some reason but thats fine! Do you believe the problem is the server script that I sent a few comments above? The one where I said “i want the script to do the opposite of what the 2nd sentence says”

This one right here is what I believe the problem is. I asked the youtuber how I could fix it in his comments but he only gave me a heart and didn’t respond