I just can't figure out what the math would be for calculating my countdown

Hey, I have a simple countdown here that goes from 100 to 0. I want value to go from 100 to 0 in 1.5 seconds. number would be the time inbetween subtracting 1 from value.

local number = X -- I NEED TO FIND X I CAN'T FIGURE IT OUT

function countDown()
	local value = 100
	repeat
		value = value - 1
		wait(number)
	until value = 0
end

I literally can’t figure out how to do this. What would the formula for finding X be, and how could I use that formula in my code?

Note: I NEED value to go from 100 to 0 in 1.5 seconds.
If I change it from 1.5 seconds in the future, I still need it to go from 100 to 0 in whatever new time I choose. I can’t find anything on the dev forum about how I would calculate this, nor can I think of a way.

This is some pretty simple percentage math which is crucial to making something like this.

So you could do time = (time you want to pass in total / the starting number)

So if you had time = (1.5 / 100) you would get 0.015 seconds between each update.

Just Use wait(X/100) in the for loop

Here’s the working script.

local number = X -- I NEED TO FIND X I CAN'T FIGURE IT OUT
fromvalue = 100
finalvalue = 0
function countDown()
for count = fromvalue, finalvalue, -1 do
		value = value - 1
		wait(X / 100)
end
end)

I also have a VERY similar count up function. How could I apply this math to that if value is 0 in the count up function? Because it is definetly not reaching 100 in 1.5 seconds, it reaches to about 50 or 60.

local lengthOfLoop = 1.5

function countUp()
	local value = 0
	local interval = lengthOfLoop/value
	repeat
		value = value + 1
		wait(interval)
	until value == 100
end

if your counting up you can just have something like this

local lengthOfLoop = 1.5

function countUp()
	local value = 0
	local endValue = 100
	
	local interval = lengthOfLoop/endValue
	repeat
		value = value + 1
		wait(interval)
	until value == endValue
end

This is odd… it still won’t reach 100 in 1.5 seconds. I will send you my full code now, it might look a bit messy.

-- Variables and Functions for the percent counter.
local lengthOfLoop = 1.5

function countUp()
	local value = 0
	local endValue = 100
	
	local interval = lengthOfLoop/endValue
	repeat
		value = value + 1
		shotPercent = value
		gui:WaitForChild("Percent").Text = tostring(shotPercent).."%"
		wait(interval)
	until shotPercent == endValue or script.Parent.Values.IsShooting.Value == false
end

function countDown()
	local value = 100
	local interval = lengthOfLoop/value
	if script.Parent.Values.IsShooting.Value == true then
		repeat
			value = value - 1
			shotPercent = value
			gui:WaitForChild("Percent").Text = tostring(shotPercent).."%"
			wait(interval)
		until shotPercent == 0 or script.Parent.Values.IsShooting.Value == false
	end
end

-- Start Counting the percent if we start shooting
script.Parent.Values.IsShooting.Changed:Connect(function()
	if script.Parent.Values.IsShooting.Value == true and script.Parent.Values.CanShoot.Value then
		countUp()
		warn("finished Counting up")
		countDown()
		warn("finished counting down")
	end
end)

What does this code mean? Well, it is for a basketball I am making. It has a shot meter, which basically determines the accuracy of the shot you are shooting. The closer the meter is to the middle, the higher shot percent is, then the farthest from the middle are the most inaccurate shots. I tween an animation that lasts three seconds. The countUp starts when the tween starts. The tween lasts 3 seconds. So, when the countUp() function finishes, the tween should be halfway done. By the time countDown() is finished, the tween should be comepleted. But, the countUp() function is DEFINITLEY not completing in time.

Sorry if this is some of the worst code you have ever read, Im not that good at scripting lol.

First of all why are you reassigning to a variable called shotpercent? Is it instantiated somewhere else in the script?

Yes. shotpercent is used elsewhere, in other functions, mainly in the part where I ask the server to handle the shooting part (which works.)

I see, also what do you mean by countup not completing in time?

In 3 seconds, both loops / repeat statements should finish. For example, value or shotPercent should be 100 exactly by the end of countUp(). By the end of countDown(), they should both be equal to 0.

How long are they taking? If it is taking something like 2-3 seconds per loop, it is probably because Roblox needs some time to run all the other code in the loop, so it takes more time then just the wait.

Can you try to benchmark aka time the functions countup and countdown and tell me how long they take to execute?

countUp() SHOULD finish in 1.5 seconds if the math is correct. You are right, it is finishing in about 2-3 seconds. I don’t understand what could be yielding it though.

I can try doing that. Would I do something like:

somethingchanged:connect(function() -- blah blah blah
      local currentTime = tick()
      countUp()
      print(currentTime - tick())
end

Something like this:

function countUp()
	local value = 0
	local endValue = 100
	local CurrentTime = tick()
	local interval = lengthOfLoop/endValue
	repeat
		value = value + 1
		shotPercent = value
		gui:WaitForChild("Percent").Text = tostring(shotPercent).."%"
		wait(interval)
	until shotPercent == endValue or script.Parent.Values.IsShooting.Value == false
        print(tick() - CurrentTime)
end

Just legit do like this

local function benchmark(Start, End)
	return (End - Start)
end


    local function countUp()
    	-- at teh top of the function put this
    	
    	local startTime = os.clock()
    	
    	-- than just handle whatever happens here
    	
    	-- at the end of the function put...
    	
    	print(benchmark(startTime, os.clock()))
    end

You were right. It took around 2.9 seconds to finish when it should have finished in 1.5. Any ideas what could be yielding it?

I mean the isshooting variable might be changing while these functions or going i don’t really know that code inefficiency might be your issue here but you can’t rule it out.

I mean, it changes to false if the player releases the shoot button in the middle of the loop, which should stop it, correct?

I gotta go, I can explain this more later. But maybe have a coroutine that only increases the value and has the wait, then in another couroutine you can run the other lines of code that changed the Gui. That way the first coroutine doesn’t have to worry about the other code, allowing it to run faster.