Need help with in-game lag

I’m trying to optimise my game and I have no clue what’s causing lag. The game gets laggier as you continue playing.

The only lead I have is the badge handler, which every second will search a bunch of stats and give out a lot of badges. If the script is needed, I will send it.


And you can just see the rate, it’s terrible

I just wanted to know if badges in general cause lag? Maybe it’s because I’m checking whether the user has the badge or not and then giving it if they don’t every second? (too many requests to badge service)

I’m not really sure. If anybody is good at this stuff let me know how I can optimise the game and badges + definitely ask me questions!

The game is called “Grocery Store Simulator” made by BWOM. It’s the first game that comes up when you search!

The script is here but it’s SUPER long so if you’re interested or bothered please do check here:

local BS = game:GetService("BadgeService")

local GAME = game.Workspace.Game
local STATS = GAME.Stats
local SETTINGS = GAME.Settings

local NUMBERSMODULE = require(game.ReplicatedStorage.Modules.Numbers)

local badges = {
	["BetaTesterBadge"] = {2151542257, false},
	["NewRecruit"] = {2151542249, false},
	["Scanner"] = {2151542639, false},
	["Restocker"] = {2151542648, false},
	["Helper"] = {2151542657, false},
	["Officer"] = {2151542671, false},
	["Cleaner"] = {2151542687, false},
	["Expansion1"] = {2151542270, false},
	["Expansion2"] = {2151542332, false},
	["Expansion3"] = {2151542576, false},
	["Ballin"] = {2151542708, false},
	["TheRichest"] = {2151542720, false},
	["SupportingSmallBusinesses"] = {2151542734, false},
	["TechExtremist"] = {2151542744, false},
	["ProperShop"] = {2151542763, false},
	["IWantToButICant"] = {2151542774, false},
	["LoadedPantry"] = {2151542777, false},
	["ThePerfectMeta"] = {2151542787, false},
	["BoredOfBoredom"] = {2151542798, false},
	["Restockinator"] = {2151542814, false},
	["RestoringFaithInHumanity"] = {2151542822, false},
	["ServingGrotsbry"] = {2151542838, false},
	["SlipDetergent"] = {2151542846, false},
}

local allbadges = {}

function LoadAllBadges(player, badgelist)
	for i, b in pairs(badgelist) do
		if BS:UserHasBadgeAsync(player.UserId, b[1]) then
			b[2] = true
		else
			b[2] = false
		end
	end
end

function AwardBadge(player, b)
	BS:AwardBadge(player.UserId, b[1])
	b[2] = true
end

if game.PlaceId ~= 14701946286 then
	game.Players.PlayerAdded:Connect(function(player)
		local badgelist = badges
		LoadAllBadges(player, badgelist)

		if badgelist.NewRecruit[2] == false then
			AwardBadge(player, badgelist.NewRecruit)
		end

		repeat wait() until player:GetAttribute("Loaded") == true

		local function ThePerfectMeta()
			game.Workspace.Extensions.ChildRemoved:Connect(function()
				if GAME.Upgrades.Extension.Value >= 1 and STATS.Day.Value <= 1 and badgelist.ThePerfectMeta[2] == false then
					AwardBadge(player, badgelist.ThePerfectMeta)
				end
			end)
		end

		local function TechExtremist()
			GAME.Badges.TechExtremist.Changed:Connect(function()
				if GAME.Badges.TechExtremist.Value >= 100 then
					if badgelist.TechExtremist[2] == false then
						AwardBadge(player, badgelist.Scanner)
					end
				end
			end)
		end

		local function SupportingSmallBusinesses()
			STATS.Day.Changed:Connect(function()
				local InTheClear = true

				if GAME.Upgrades.Supplier.Value == "Grotsbry Local" then
					local Changed 

					Changed = GAME.Upgrades.Supplier.Changed:Connect(function()
						if GAME.Upgrades.Supplier.Value ~= "Grotsbry Local" then
							InTheClear = false
							Changed:Disconnect()
						end
					end)

					local currentday = STATS.Day.Value

					repeat wait() until STATS.Day.Value > currentday
					Changed:Disconnect()

					if InTheClear == true and badgelist.SupportingSmallBusinesses[2] == false then
						AwardBadge(player, badgelist.SupportingSmallBusinesses)
					end
				else
					InTheClear = false
				end
			end)
		end

		local function LoadedPantry()
			STATS.Day.Changed:Connect(function()
				local InTheClear = true

				local Changed

				Changed = game.ReplicatedStorage.Events.Binds.OnServerEvent:Connect(function(todo)
					if todo == "Order" then
						InTheClear = false
						Changed:Disconnect()
					end
				end)

				local currentday = STATS.Day.Value

				repeat wait() until STATS.Day.Value > currentday
				Changed:Disconnect()

				if InTheClear == true and badgelist.LoadedPantry[2] == false then
					AwardBadge(player, badgelist.LoadedPantry)
				end
			end)
		end

		local function ProperShop()
			local function CheckAllQualityUpgrades()
				local AllMaxed = true

				for i, q in pairs(GAME.Upgrades:GetChildren()) do
					if game.ReplicatedStorage.Upgrades.Quality:FindFirstChild(q.Name) then
						local MaxedNumber = 0

						for i, qq in pairs(game.ReplicatedStorage.Upgrades.Quality:FindFirstChild(q.Name):GetChildren()) do
							MaxedNumber += #qq:GetChildren()
						end

						if q.Value < MaxedNumber then
							AllMaxed = false
							break
						else
						end
					end
				end

				return AllMaxed
			end

			for i, q in pairs(GAME.Upgrades:GetChildren()) do
				if game.ReplicatedStorage.Upgrades.Quality:FindFirstChild(q.Name) then
					q.Changed:Connect(function()
						if CheckAllQualityUpgrades() == true and badgelist.ProperShop[2] == false then
							AwardBadge(player, badgelist.ProperShop)
						end
					end)
				end
			end
		end

		local function IWantToButICant()
			GAME.Server.Event.Changed:Connect(function()
				if GAME.Server.Event.Value == "Heist" then
					GAME.Badges.IWantToButICant.Value = 0
					GAME.Server.Event.Changed:Wait()

					if GAME.Badges.IWantToButICant.Value == 0 and badgelist.IWantToButICant[2] == false then
						AwardBadge(player, badgelist.IWantToButICant)
					end
				end
			end)
		end

		ProperShop()
		LoadedPantry()
		SupportingSmallBusinesses()
		IWantToButICant()
		ThePerfectMeta()
		TechExtremist()

		-- stat based badges

		while wait(10) do
			if player then
				if player.stats.Helped.Value >= 25 then
					if badgelist.Helper[2] == false then
						AwardBadge(player, badgelist.Helper)
					end
				end 

				if player.stats.Helped.Value >= 100 then
					if badgelist.RestoringFaithInHumanity[2] == false then
						AwardBadge(player, badgelist.RestoringFaithInHumanity)
					end
				end

				if player.stats.Scanned.Value >= 100 and badgelist.Scanner[2] == false then
					AwardBadge(player, badgelist.Scanner)
				end

				if player.stats.Scanned.Value >= 1000 and badgelist.BoredOfBoredom[2] == false then
					AwardBadge(player, badgelist.BoredOfBoredom)
				end

				if player.stats.Restocked.Value >= 100 and badgelist.Restocker[2] == false then
					AwardBadge(player, badgelist.Restocker)
				end

				if player.stats.Restocked.Value >= 1000 and badgelist.Restockinator[2] == false then
					AwardBadge(player, badgelist.Restockinator)
				end

				if player.stats.Arrested.Value >= 5 and badgelist.Officer[2] == false then
					AwardBadge(player, badgelist.Officer)
				end

				if player.stats.Arrested.Value >= 100 and badgelist.ServingGrotsbry[2] == false then
					AwardBadge(player, badgelist.ServingGrotsbry)
				end

				if player.stats.Cleaned.Value >= 50 and badgelist.Cleaner[2] == false then
					AwardBadge(player, badgelist.Cleaner)
				end

				if player.stats.Cleaned.Value >= 450 and badgelist.SlipDetergent[2] == false then
					AwardBadge(player, badgelist.SlipDetergent)
				end

				if player.leaderstats.Cash.Value >= 1000 and badgelist.Ballin[2] == false then
					AwardBadge(player, badgelist.Ballin)
				end

				if player.leaderstats.Cash.Value >= 10000 and badgelist.TheRichest[2] == false then
					AwardBadge(player, badgelist.TheRichest)
				end

				if GAME.Upgrades.Extension.Value == 1 and badgelist.Expansion1[2] == false then
					AwardBadge(player, badgelist.Expansion1)
				end

				if GAME.Upgrades.Extension.Value == 2 and badgelist.Expansion2[2] == false then
					AwardBadge(player, badgelist.Expansion2)
				end

				if GAME.Upgrades.Extension.Value == 3 and badgelist.Expansion3[2] == false then
					AwardBadge(player, badgelist.Expansion3)
				end
			else
				break
			end
		end
	end)
end
1 Like

It looks like there’s a loop in the code that causes it to run over and over again. What does the loop look like?

Can you show your badge handler code?

Try disabling that script to see if that fixes it.

with rates that big
the only thing i can suspect is RunService loop inside of a RunService loop lol

my laggiest “normal” scripts never go past 350

The most probable reason to why the game is consuming a lot of device ram and causing itself to lag is because of an infinite loop ( Which is most likely the reason to be ). Head over to your localscript or serverscript where the BadgeHandler is located and check it’s code structure to find if there’s any infinite loop. There will surely be an infinite loop in that specified script so in order to optimize the script, you can add in a task.wait() function with no parametric value which is almost ~0. I dont recommend the task.wait() function solution so another way of solving this issue can by adding a break statement into your infinite loop so when all the code functionality is done, it will automatically break and then close the loop. Another way which you can look upon is by changing your code entirely of the BadgeHandler and using a game:GetService(“Players”).PlayersAdded event ( I am not sure what your code does so I am taking consideration that you just want to give or take the Badges ).

Without a script to look at, everything is just a guess …
Never seen a Rate that high. Looks like you have a task(s) by the same name running as an interrupt, going at wrap speed in a loop. Or just a loop without any real stall to it.

local rs = game:GetService("RunService")
rs.Stepped:Wait()

Is a golden command. Not only stalls but it stalls in sync with the screen update.
This makes it so it’s not going to hurt your graphics elsewhere …

If you can provide us with the BadgeHandler script, we’ll be able to help you optimize it. To me this looks like you have loop(s) that aren’t being cleaned up.

It’s super long but the main part you need to focus on is the while wait(10) do at the end

local BS = game:GetService("BadgeService")

local GAME = game.Workspace.Game
local STATS = GAME.Stats
local SETTINGS = GAME.Settings

local NUMBERSMODULE = require(game.ReplicatedStorage.Modules.Numbers)

local badges = {
	["BetaTesterBadge"] = {2151542257, false},
	["NewRecruit"] = {2151542249, false},
	["Scanner"] = {2151542639, false},
	["Restocker"] = {2151542648, false},
	["Helper"] = {2151542657, false},
	["Officer"] = {2151542671, false},
	["Cleaner"] = {2151542687, false},
	["Expansion1"] = {2151542270, false},
	["Expansion2"] = {2151542332, false},
	["Expansion3"] = {2151542576, false},
	["Ballin"] = {2151542708, false},
	["TheRichest"] = {2151542720, false},
	["SupportingSmallBusinesses"] = {2151542734, false},
	["TechExtremist"] = {2151542744, false},
	["ProperShop"] = {2151542763, false},
	["IWantToButICant"] = {2151542774, false},
	["LoadedPantry"] = {2151542777, false},
	["ThePerfectMeta"] = {2151542787, false},
	["BoredOfBoredom"] = {2151542798, false},
	["Restockinator"] = {2151542814, false},
	["RestoringFaithInHumanity"] = {2151542822, false},
	["ServingGrotsbry"] = {2151542838, false},
	["SlipDetergent"] = {2151542846, false},
}

local allbadges = {}

function LoadAllBadges(player, badgelist)
	for i, b in pairs(badgelist) do
		if BS:UserHasBadgeAsync(player.UserId, b[1]) then
			b[2] = true
		else
			b[2] = false
		end
	end
end

function AwardBadge(player, b)
	BS:AwardBadge(player.UserId, b[1])
	b[2] = true
end

if game.PlaceId ~= 14701946286 then
	game.Players.PlayerAdded:Connect(function(player)
		local badgelist = badges
		LoadAllBadges(player, badgelist)

		if badgelist.NewRecruit[2] == false then
			AwardBadge(player, badgelist.NewRecruit)
		end

		repeat wait() until player:GetAttribute("Loaded") == true

		local function ThePerfectMeta()
			game.Workspace.Extensions.ChildRemoved:Connect(function()
				if GAME.Upgrades.Extension.Value >= 1 and STATS.Day.Value <= 1 and badgelist.ThePerfectMeta[2] == false then
					AwardBadge(player, badgelist.ThePerfectMeta)
				end
			end)
		end

		local function TechExtremist()
			GAME.Badges.TechExtremist.Changed:Connect(function()
				if GAME.Badges.TechExtremist.Value >= 100 then
					if badgelist.TechExtremist[2] == false then
						AwardBadge(player, badgelist.Scanner)
					end
				end
			end)
		end

		local function SupportingSmallBusinesses()
			STATS.Day.Changed:Connect(function()
				local InTheClear = true

				if GAME.Upgrades.Supplier.Value == "Grotsbry Local" then
					local Changed 

					Changed = GAME.Upgrades.Supplier.Changed:Connect(function()
						if GAME.Upgrades.Supplier.Value ~= "Grotsbry Local" then
							InTheClear = false
							Changed:Disconnect()
						end
					end)

					local currentday = STATS.Day.Value

					repeat wait() until STATS.Day.Value > currentday
					Changed:Disconnect()

					if InTheClear == true and badgelist.SupportingSmallBusinesses[2] == false then
						AwardBadge(player, badgelist.SupportingSmallBusinesses)
					end
				else
					InTheClear = false
				end
			end)
		end

		local function LoadedPantry()
			STATS.Day.Changed:Connect(function()
				local InTheClear = true

				local Changed

				Changed = game.ReplicatedStorage.Events.Binds.OnServerEvent:Connect(function(todo)
					if todo == "Order" then
						InTheClear = false
						Changed:Disconnect()
					end
				end)

				local currentday = STATS.Day.Value

				repeat wait() until STATS.Day.Value > currentday
				Changed:Disconnect()

				if InTheClear == true and badgelist.LoadedPantry[2] == false then
					AwardBadge(player, badgelist.LoadedPantry)
				end
			end)
		end

		local function ProperShop()
			local function CheckAllQualityUpgrades()
				local AllMaxed = true

				for i, q in pairs(GAME.Upgrades:GetChildren()) do
					if game.ReplicatedStorage.Upgrades.Quality:FindFirstChild(q.Name) then
						local MaxedNumber = 0

						for i, qq in pairs(game.ReplicatedStorage.Upgrades.Quality:FindFirstChild(q.Name):GetChildren()) do
							MaxedNumber += #qq:GetChildren()
						end

						if q.Value < MaxedNumber then
							AllMaxed = false
							break
						else
						end
					end
				end

				return AllMaxed
			end

			for i, q in pairs(GAME.Upgrades:GetChildren()) do
				if game.ReplicatedStorage.Upgrades.Quality:FindFirstChild(q.Name) then
					q.Changed:Connect(function()
						if CheckAllQualityUpgrades() == true and badgelist.ProperShop[2] == false then
							AwardBadge(player, badgelist.ProperShop)
						end
					end)
				end
			end
		end

		local function IWantToButICant()
			GAME.Server.Event.Changed:Connect(function()
				if GAME.Server.Event.Value == "Heist" then
					GAME.Badges.IWantToButICant.Value = 0
					GAME.Server.Event.Changed:Wait()

					if GAME.Badges.IWantToButICant.Value == 0 and badgelist.IWantToButICant[2] == false then
						AwardBadge(player, badgelist.IWantToButICant)
					end
				end
			end)
		end

		ProperShop()
		LoadedPantry()
		SupportingSmallBusinesses()
		IWantToButICant()
		ThePerfectMeta()
		TechExtremist()

		-- stat based badges

		while wait(10) do
			if player then
				if player.stats.Helped.Value >= 25 then
					if badgelist.Helper[2] == false then
						AwardBadge(player, badgelist.Helper)
					end
				end 

				if player.stats.Helped.Value >= 100 then
					if badgelist.RestoringFaithInHumanity[2] == false then
						AwardBadge(player, badgelist.RestoringFaithInHumanity)
					end
				end

				if player.stats.Scanned.Value >= 100 and badgelist.Scanner[2] == false then
					AwardBadge(player, badgelist.Scanner)
				end

				if player.stats.Scanned.Value >= 1000 and badgelist.BoredOfBoredom[2] == false then
					AwardBadge(player, badgelist.BoredOfBoredom)
				end

				if player.stats.Restocked.Value >= 100 and badgelist.Restocker[2] == false then
					AwardBadge(player, badgelist.Restocker)
				end

				if player.stats.Restocked.Value >= 1000 and badgelist.Restockinator[2] == false then
					AwardBadge(player, badgelist.Restockinator)
				end

				if player.stats.Arrested.Value >= 5 and badgelist.Officer[2] == false then
					AwardBadge(player, badgelist.Officer)
				end

				if player.stats.Arrested.Value >= 100 and badgelist.ServingGrotsbry[2] == false then
					AwardBadge(player, badgelist.ServingGrotsbry)
				end

				if player.stats.Cleaned.Value >= 50 and badgelist.Cleaner[2] == false then
					AwardBadge(player, badgelist.Cleaner)
				end

				if player.stats.Cleaned.Value >= 450 and badgelist.SlipDetergent[2] == false then
					AwardBadge(player, badgelist.SlipDetergent)
				end

				if player.leaderstats.Cash.Value >= 1000 and badgelist.Ballin[2] == false then
					AwardBadge(player, badgelist.Ballin)
				end

				if player.leaderstats.Cash.Value >= 10000 and badgelist.TheRichest[2] == false then
					AwardBadge(player, badgelist.TheRichest)
				end

				if GAME.Upgrades.Extension.Value == 1 and badgelist.Expansion1[2] == false then
					AwardBadge(player, badgelist.Expansion1)
				end

				if GAME.Upgrades.Extension.Value == 2 and badgelist.Expansion2[2] == false then
					AwardBadge(player, badgelist.Expansion2)
				end

				if GAME.Upgrades.Extension.Value == 3 and badgelist.Expansion3[2] == false then
					AwardBadge(player, badgelist.Expansion3)
				end
			else
				break
			end
		end
	end)
end

change that to:

while true do
     wait(10)

and see if that fixes it

You are using wait(10) as a condition of the while loop, idk if that is supposed to work but its odd.

It’s actually really odd that it’s hogging resources even though you’re waiting 10 seconds. Is the resource consumption still high outside of Studio? Also, i would like to suggest using task.wait() instead of wait()!

The wait in this case should be replaced with task.wait if you’re experiencing lag problems. This is because of throttling. In some cases, throttling is a good thing, but not here.

Yeah, it does, but it’s slower. The engine is specifically optimized for while true do loops. wait returns two numbers.

Refrain from using infinite loops when you don’t need them.