Need help fixing lag in my game

So my game has a massive issue: Lag. The game seems to get laggier the longer you play for and the entire game deteriorates after only a few hours.

My only lead is the BadgeHandler inside the game which processes all the badges for players.
Here is it’s rate:


I’ve been told that this is apparently just way way way too much, which I’ve now figured.

Also: The lag seems to stop and the cycle seems to restart once you rejoin the game. However I’m sure it’s badgeHandler (which is a normal script) as that would mean it’s a client issue.

Here’s the script, it’s very long so I’d really appreciate anybody who wants skim through.

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

Any help is much appreciated + Ask me questions, I’m more than happy to help solve this too!

Wait, why are you using while wait(10) do ? And why are you doing it for each player, in a script ?

This may be the cause of the extreme Rate(/s). I don’t believe you need to repeatedly check something instead you can use value.Changed.

I am sure you can narrow down this script big time as well (optimizing it also reduces lag I believe)

Also: The lag seems to stop and the cycle seems to restart once you rejoin the game. However I’m sure it’s badgeHandler (which is a normal script) as that would mean it’s a client issue.

I am pretty sure this is not a client issue since I am guessing this is a script and not a local script. Try playing with 2 players, I am sure it will reduce the Rate(/s) by half when a player leaves.

Explained

You are constantly checking for multiple players a huge amount of values at the same time. When a player leaves, the loop breaks for that certain player but not for the others so the Rate(/s) used for that certain player gets removed. (Let’s say there’s 2 players and each player uses 30 Rate(/s) that means the total Rate(/s) for the server side is going to be 60 and not 30 [this is due to you looping for multiple players in the server side]

Possible solution

So I am guessing what you can do is to first check stats from the local side then if the requirements are met tell the server side to check again and award the badge accordingly.

Note : I may not have well explained the problem or maybe even my explanation was wrong. If so I am truly sorry.

2 Likes

I would recommend putting print statements in your loops and/or functions to see which one is spamming. You should find something cycling very quickly, not 10 seconds, many times per second.

in this case if u do want to fix lag in ur game, i’d recommend to like start debugging ur game, to basically see whats going wrong and other stuff, and dont forgot dont repeat urself and try to make ur lines of codes as short as possible but just as efficient/optimized as you could think