Alternative to for loop?

Hi! I have rebirths in my game with different rebirth amounts. When you buy a rebirth, it increases by a little but. So buying 5 rebirths will not be 5x One rebirth, it will be the same amount as buying one rebirth five times and since the rebirth increases every time you buy it, the 5 rebirth final cost will be way more than one rebirth final cost. I use a for do loop to calculate this. However, when you get to something like a 15M+ Rebirth button, it lags a lot. How should I fix this?

local button = script.Parent
local plr = game.Players.LocalPlayer
local rebirthRE = game:GetService("ReplicatedStorage"):WaitForChild("rebirth")

local final_cost = 0

local buttonNum = 9

function roundNumber(num, numDecimalPlaces)
	return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
end

local abbreviations = {
	"K", -- 4 digits
	"M", -- 7 digits
	"B", -- 10 digits
	"T", -- 13 digits
	"QD", -- 16 digits
	"QT", -- 19 digits
	"SXT", -- 22 digits
	"SEPT", -- 25 digits
	"OCT", -- 28 digits
	"NON", -- 31 digits
	"DEC", -- 34 digits
	"UDEC", -- 37 digits
	"DDEC", -- 40 digits
}

local function Abbreviate(x)
	if x < 1000 then 
		return tostring(x)
	end

	local digits = math.floor(math.log10(x)) + 1
	local index = math.min(#abbreviations, math.floor((digits - 1) / 3))
	local front = x / (math.pow(10, index * 3))
	
	local Front = roundNumber(front, 2)

	return Front .."".. abbreviations[index] .."+"
end

local function createFinalCost(num)
	final_cost += (plr:WaitForChild("leaderstats"):WaitForChild("Rebirths").Value + num) * 50
end

for i = 1, script.Parent.Parent.RebirthAmount.Value do
	createFinalCost(i)
end

script.Parent.Parent.CrownAmount.Text = (Abbreviate(final_cost)) .." Crowns"

if plr:WaitForChild("RebirthButtonAmount").Value >= buttonNum then
	script.Parent.Lock.Visible = false
end

button.MouseButton1Click:Connect(function()
	if script.Parent.Lock.Visible == false then
		if plr:WaitForChild("leaderstats"):WaitForChild("Crowns").Value >= final_cost then
			rebirthRE:FireServer(final_cost, script.Parent.Parent.RebirthAmount.Value)
		end
	end
end)

plr:WaitForChild("leaderstats"):WaitForChild("Rebirths").Changed:Connect(function()
	final_cost = 0
	for i = 1, script.Parent.Parent.RebirthAmount.Value do
		createFinalCost(i)
	end

	script.Parent.Parent.CrownAmount.Text = (Abbreviate(final_cost)) .." Crowns"
end)

plr:WaitForChild("RebirthButtonAmount").Changed:Connect(function()
	if plr:WaitForChild("RebirthButtonAmount").Value >= buttonNum then
		script.Parent.Lock.Visible = false
	end
end)

I hoped this made sense, I can explain it better if needed

1 Like

Start by adding this function

 local function getCost()
	local rebirthVal = plr:WaitForChild("leaderstats"):WaitForChild("Rebirths").Value
	final_cost += rebirthVal * ((rebirthVal + num) * 50)
end

EDIT: Added WaitForChild idk why I forgot that

Replace THIS (in all your code)
for i = 1, script.Parent.Parent.RebirthAmount.Value do
	createFinalCost(i)
end
With THIS (in all your code
getCost()
1 Like

what will num be? In my code num was the number of times that the loop has been looped

1 Like

Taking a second look, I don’t know why you would want to use a factorial to determine the price of a Rebirth. Correct me if I’m totally wrong here, but if you want it to grow at a linear rate:
price = num_of_rebirths * 50
or at an exponential rate:
price = a(b)^num_of_rebirths
where a is your starting price, and b is your rate of growth

2 Likes

You can actually just use multiplication instead of a loop in this case because your just increasing the final cost for every rebirth.

For example, something like this

for i = 1, 10 do
    something += 1 + 4
end

could be simplified into something like this

something += (1 + 4) * 10

because in this loop, its just running something += 1 + 4 ten times, so multiplying the result of 1 + 4 by 10 would be the same as adding 1 + 4 to something 10 times


Also, side note, but I noticed you use WaitForChild several times on the same object. I would recommend to store any WaitForChild calls inside of a variable instead as it can shorten your code and improve readability.

Eg, instead of doing plr:WaitForChild("leaderstats") every time you want to get leaderstats, you could just do local leaderstats = plr:WaitForChild("leaderstats") and whenever you want to access leaderstats, you just use that variable leaderstats.

1 Like