Is there a way to make this timer more efficient?

I decided to make a little timer for obbies or anything that could use a timer. When a player touches the first part of the track, the timer will begin and when he touches the last part, the timer will finish.

I wanted to show the player his timing(always updating) so there is a little sense of urgency or something. I thought that to not eat a lot of resources, the updating thing to be done on the client and the true start and finish times to be memorised on the server. At the end, a simple “finish - start” will give you his race timer, but I happen to see a little difference of a few milliseconds between times (it seems like a difference of a “wait()”) and I was wondering if you knew any better idea to do this. (more performance friendly and/or more accurate).

I do mention that there will be most 6 players in a game. (If there will be like 20, will this be influenced much?)

Server script when within the “start” part

local event = game:GetService("ReplicatedStorage").Timer

script.Parent.Touched:Connect(function(part)
	if part.Parent:FindFirstChild('Humanoid') then
		local tk = tick()
		local player = game.Players:GetPlayerFromCharacter(part.Parent)
		local ref = game:GetService("ServerStorage").Racing:WaitForChild(player.Name)
		if ref.InRace.Value == false then
			ref.InRace.Value = true
			ref.Start.Value = tk
			event:FireClient(player, 1) -- 1: start the client timer, 2: stop the client timer
		end
		end
end)

Server script within the “finish” part

local event = game:GetService("ReplicatedStorage").Timer

script.Parent.Touched:Connect(function(part)
	if part.Parent:FindFirstChild('Humanoid') then
		local tk = tick()
		local player = game.Players:GetPlayerFromCharacter(part.Parent)
		local ref = game:GetService("ServerStorage").Racing:WaitForChild(player.Name)
		if  ref.InRace.Value == true then
			print(tk - ref.Start.Value)
			ref.InRace.Value = false
			event:FireClient(player, 2)
		end
	end
end)

Local Script that shows the player (on the client) his timing

local event = game:GetService("ReplicatedStorage").Timer

local run = true
local tick2 = 0

local deb = false
local function timer()
	print(deb)
	print(run)
	if deb == false then
		run = true
		print("entered")
		deb = true
		local tick1 = tick()
		while run == true do
			wait()
			tick2 = tick() - tick1
			print(tick2)
		end
	end
end

local function stopp()
	run = false
	deb = false
	print("Congrat on time: "..tick2)
end

local function choose(x)
	if x == 1 then
		timer()
	end
	if x == 2  then
		stopp()
	end
end

event.OnClientEvent:Connect(choose)

This will be the method of storing the variables for a single run:
https://gyazo.com/680fdb17a03297a68ef04f2de446d1fa

Here I let the script run a few times, these are the timings:
(The timer printed by “script” will be the “true” one and the timing on “Congrat…” will be the local one)
https://gyazo.com/6bf8732628f1fd4ed94c5297d4e183b5
https://gyazo.com/53d8fc371790c600a51d586884304381
https://gyazo.com/038226f42acafe790e0bca4d42606c96

P.S. I am not that great at scripting nor Roblox scripting, so try to not be very harsh with me for any “atrocities” that may appear. I tried to make it look as readable as possible.

1 Like

You can actually store only 1 variable.

local lasttime = os.clock()

local function timer()
  if not deb then
    deb = true
    lasttime = os.clock()
  end
end

local function stop()
  print(os.clock() - lasttime)
end

Also, instead of doing

if x == 1 then
  something()
end

if x == 3 then
  somethingelse()
end

do:

if x == 1 then
  something()
elseif x == 3 then
  somethingelse()
end

if there is no gap (or just small gap) between them ( and they are all above above -1 and are integers), an array can be used instead (Here I didn’t cache the reference for illustrative purposes)

local arr = {[1] = something, [2] = false, [3] = somethingelse}
if arr[x] then
  arr[x]()
end

however, if there is big gap and little cases, at least use elseif

if x == 0 then
  something()
elseif x == 213546 then
  somethingelse()
end

If there are a lot of cases and there are gaps, use a dictionary.

local t = {[-45] = foo, [-5436] = bar, [123] = foobar, [21234235] = barfoo}
if t[case] then
  t[case]()
end
1 Like