Game disconnecting players with constant up spike in thread memory

Every so often, players from my game have been disconnected from a server. I had no idea why until I looked at the Dev Console when I experienced a disconnect myself.

Thread Memory(Server):

If anyone can give me some help and tips on why this is doing this and how to prevent it would be much appreciated.

This problem is difficult to solve without looking at your code closely. Have you created an infinite loop that generate parts inside workspace? I guess that there is some kind of loops that doing huge things without stopping.

Or you may use spawn() command that create a new thread over and over, but the new thread cannot complete its job. So, as a result, millions of threads are being created at the short amount of time.

I see, I apologize if I didn’t elaborate correctly, the game constantly builds up memory in a medium amount of time.

Have you tried delete some parts of code and see if the problem persists? If you find the code that breaks your game, you can post it in here and we will go from there.

Does anyone know what’s going on, I still can’t track whats causing it and its ruining my game.

Have you tried what I mentioned above? By removing some parts of your code. Use Find All feature inside the Studio and search for all loops that you have implemented. We cannot help you much without seeing a script, you know… But posting your script for your entrie game makes no sense either.

Couldn’t find anything that could cause it, getting desperate now :slightly_frowning_face:

As I said, without seeing your script, we cannot help you more than making a guess on what is wrong with your code. Have you tried checking what I said above?

A quick check of the active memory used by your game should give you clues. As @Jacky2804 has said, we don’t know your code, we can’t see your code, so cannot guide you as to where to look in your code for the problem.

I’d guess that somewhere in your code you are spawning new threads and then never terminating them. Look for spawned infinite loops and that could be your answer. I know I had a similar issue with a projectile movement loop that did a similar thing.

1 Like

I cant show you my code cause there are multiple scripts and I don’t know whats causing it.

The Developer Console should be able to give you some clues, check Scripts for scripts that are running the most code, likeliest suspect, and I think there are is script memory usage information in the same memory viewing section, under maybe PlaceScriptMemory or something similar?

Unable to catch a crash yet but would repeat wait until somehow cause this as this is used a lot in my game

Yep you may right. You have to find the one that keep repeating infinitely.

1 Like

:warning: More Info Found

Managed to catch a crash and it’s in the core memory, What on earth do I do


It’s in the RBXTHREAD section of the memory.

Can you check the Scripts section?


Here it is, nothing looks unusual.

Thats unusual? What does rate mean?

High rates means you use a lot of loops, what’s inside Ai?

A lot of code is incoming.

Normal AI Code:

local Info = { 
	MonsterName = "Muffet", --Name of the enemy 
	RangeofVision = 1000, --Range where the enemy can see you
	AttackActivationRange = 1000, --Range where monster starts to attack
	AttackOrderRandom = false, --If the monster has no order with attacks
	AttackOrder = {"Spider","Donut","Donut","Croissant","Croissant","Croissant","Spider"}, --Above must be true to this to work (put the names of scripts in order) 
	Hitspeed = 2, --Attack Speed,
	
	DamageInfo = { --A dictionary of damages
		Default = 3, --It can also be a function! like for example Default = function(Player) Player:Kick("poop") end) !
	},
	
	AttackOrders = {
		{Condition = 2250, Order = {"Spider","Donut","Donut","Croissant","Croissant","Donut","Spider","Croissant","Croissant","Spider"}, Hitspeed = 1.5,
		} --Condition is how much HP is needed at least for the attack order to be changed to this. It can also be a function for a custom check.
	},
	
	DeathEffect = function() --Optional, this function fires when the character dies.
		script.Parent.HumanoidRootPart.Anchored = true

		for _,CharObject in pairs(script.Parent:GetDescendants()) do
			if CharObject:IsA('Accessory')  then
				CharObject:Destroy()
			else if CharObject:IsA('Hat') then
					CharObject:Destroy()
				else if CharObject:IsA('Part') or CharObject:IsA('MeshPart') or CharObject:IsA('UnionOperation') then
						game.TweenService:Create(CharObject,TweenInfo.new(1),{Transparency = 1}):Play()
					end
				end
			end
		end

		script.Parent.HumanoidRootPart.Dust:Play()
		wait(3)
		script.Parent:Destroy()
	end,
}
-------------------------------------------------------------------------------------------------
require(game.ServerScriptService.Modules.AIBase)(script.Parent, Info)

local Info = { 
	MonsterName = "Muffet", --Name of the enemy 
	RangeofVision = 1000, --Range where the enemy can see you
	AttackActivationRange = 1000, --Range where monster starts to attack
	AttackOrderRandom = false, --If the monster has no order with attacks
	AttackOrder = {"Spider","Donut","Donut","Croissant","Croissant","Croissant","Spider"}, --Above must be true to this to work (put the names of scripts in order) 
	Hitspeed = 2, --Attack Speed,
	
	DamageInfo = { --A dictionary of damages
		Default = 3, --It can also be a function! like for example Default = function(Player) Player:Kick("poop") end) !
	},
	
	AttackOrders = {
		{Condition = 2250, Order = {"Spider","Donut","Donut","Croissant","Croissant","Donut","Spider","Croissant","Croissant","Spider"}, Hitspeed = 1.5,
		}
	},
	
	DeathEffect = function() --Optional, this function fires when the character dies.
		script.Parent.HumanoidRootPart.Anchored = true

		for _,CharObject in pairs(script.Parent:GetDescendants()) do
			if CharObject:IsA('Accessory')  then
				CharObject:Destroy()
			else if CharObject:IsA('Hat') then
					CharObject:Destroy()
				else if CharObject:IsA('Part') or CharObject:IsA('MeshPart') or CharObject:IsA('UnionOperation') then
						game.TweenService:Create(CharObject,TweenInfo.new(1),{Transparency = 1}):Play()
					end
				end
			end
		end

		script.Parent.HumanoidRootPart.Dust:Play()
		wait(3)
		script.Parent:Destroy()
	end,
}
-------------------------------------------------------------------------------------------------
require(game.ServerScriptService.Modules.AIBase)(script.Parent, Info)

In the AI Base is this code:

return function(Character, Info)
	
	if Character:FindFirstChild("Damage") then
		Character.Damage.OnServerEvent:connect(function(Player, Name)
			if Info.DamageInfo and Info.DamageInfo[Name] then
				if typeof(Info.DamageInfo[Name]) == "number" then
					Player.Character.Humanoid:TakeDamage(Info.DamageInfo[Name])
				elseif typeof(Info.DamageInfo[Name]) == "function" then
					Info.DamageInfo[Name](Player)
				end
			end
		end)
	else
		warn("Add a remote event called Damage to ",Character,"for damaging!")
	end

	local CurrentAOIndex = 0
	local MovedEvents = {}

	local enemytag = Instance.new("ObjectValue")
	enemytag.Name = "_enemytag"
	enemytag.Parent = Character
	Character.Humanoid.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOff
	Character.Humanoid.NameDisplayDistance = 0
	Character.Humanoid.BreakJointsOnDeath = false
	local stats = game.Lighting.Stats:Clone()
	stats.MonsterName.Text = Info.MonsterName
	stats.HP.Text.Text = "HP "..math.floor(Character.Humanoid.Health).."/"..math.floor(Character.Humanoid.MaxHealth)
	stats.HP.Bar.Size = UDim2.new(Character.Humanoid.Health/Character.Humanoid.MaxHealth,0,1,0)
	stats.Parent = Character.Head
	local order = 1
	Character.Humanoid.Died:connect(function()
		if Info.DeathEffect then
			Info.DeathEffect()
			
		
		end
	end)
	Character.Humanoid.Changed:connect(function()
		stats.HP.Text.Text = "HP "..Character.Humanoid.Health.."/"..Character.Humanoid.MaxHealth
		stats.HP.Bar.Size = UDim2.new(Character.Humanoid.Health/Character.Humanoid.MaxHealth,0,1,0)
	end)
	
	
	local target = nil 
	local function FindTarget()
		local dist = Info.RangeofVision
		local found = nil
		local c = workspace:GetChildren()
		for i=1,#c do
			if c[i]:FindFirstChild("HumanoidRootPart") and c[i]:FindFirstChild("Humanoid") and c[i].Humanoid.Health > 0  and c[i]:FindFirstChild("_enemytag") == nil and c[i] ~= Character and (Character.HumanoidRootPart.Position - c[i].HumanoidRootPart.Position).Magnitude <= dist then
				dist = (Character.HumanoidRootPart.Position - c[i].HumanoidRootPart.Position).Magnitude
				found = c[i]
			end
		end
		target = found
	end

	local function Move()
		local path = game:GetService("PathfindingService"):FindPathAsync(Character.HumanoidRootPart.Position,target.HumanoidRootPart.Position)
		local wp = path:GetWaypoints()
		if #wp >= 4 then
			Character.Humanoid.WalkToPoint = wp[4].Position
			if wp[4].Action == Enum.PathWaypointAction.Jump then
				Character.Humanoid.Jump = true
			end
		elseif #wp >= 3 then
			Character.Humanoid.WalkToPoint = wp[3].Position
			if wp[3].Action == Enum.PathWaypointAction.Jump then
				Character.Humanoid.Jump = true
			end
		elseif #wp >= 2 then
			Character.Humanoid.WalkToPoint = wp[2].Position
			if wp[2].Action == Enum.PathWaypointAction.Jump then
				Character.Humanoid.Jump = true
			end
		elseif #wp >= 1 then
			Character.Humanoid.WalkToPoint = wp[1].Position
			if wp[1].Action == Enum.PathWaypointAction.Jump then
				Character.Humanoid.Jump = true
			end
		else
			Character.Humanoid.WalkToPoint = target.HumanoidRootPart.Position
		end
	end
	
	local function GetAttackOrder()
		if Info.AttackOrders == nil then return Info.AttackOrder end
		local Return, Index = Info.AttackOrder, CurrentAOIndex
		for i, Order in ipairs(Info.AttackOrders) do
			if Order.Condition and (typeof(Order.Condition) == "number" and Character.Humanoid.Health <= Order.Condition or typeof(Order.Condition) == "function" and Order.Condition()) then
				Return = Order
				Index = i
			end
		end
		return Return, Index
	end
	
	local speed = Character.Humanoid.WalkSpeed
	local PlayersInBattle = Character.Players:GetChildren()
	
	for _,PlayersBattle in pairs(PlayersInBattle) do
		if PlayersBattle.Value.Character:FindFirstChild('Humanoid') == false then continue end
		
		if Character and (Character:FindFirstChildOfClass("Humanoid") == nil or Character:FindFirstChildOfClass("Humanoid").Health > 0) then
			task.wait()
			FindTarget()
			local plrs = {}
			local c = Character.Players:GetChildren()
			for i=1,#c do
				table.insert(plrs,c[i].Value)
			end
			local NewOrder, NOIndex = GetAttackOrder()
			if NOIndex ~= CurrentAOIndex then
				Info.AttackOrder = NewOrder.Order or Info.AttackOrder
				Info.Hitspeed = NewOrder.Hitspeed or Info.Hitspeed
				CurrentAOIndex = NOIndex
				order = 1
			end
			if target and target.Parent and target:FindFirstChild("HumanoidRootPart") then
				if (Character.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude > Info.AttackActivationRange then
					Move() 
					Character.Humanoid.WalkSpeed = speed
				else 
					Character.Humanoid.WalkSpeed = 0.05
					Character.Humanoid.WalkToPoint = target.HumanoidRootPart.Position

				end
			end
		end
		
	MovedEvents[PlayersBattle.Value] = PlayersBattle.Value.Character.Humanoid.Changed:Connect(function()
	if Character and (Character:FindFirstChildOfClass("Humanoid") == nil or Character:FindFirstChildOfClass("Humanoid").Health > 0) then
		task.wait()
		FindTarget()
		local plrs = {}
		local c = Character.Players:GetChildren()
		for i=1,#c do
			table.insert(plrs,c[i].Value)
		end
		local NewOrder, NOIndex = GetAttackOrder()
		if NOIndex ~= CurrentAOIndex then
			Info.AttackOrder = NewOrder.Order or Info.AttackOrder
			Info.Hitspeed = NewOrder.Hitspeed or Info.Hitspeed
			CurrentAOIndex = NOIndex
			order = 1
		end
		if target and target.Parent and target:FindFirstChild("HumanoidRootPart") then
			if (Character.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude > Info.AttackActivationRange then
				Move() 
				Character.Humanoid.WalkSpeed = speed
			else 
				Character.Humanoid.WalkSpeed = 0.05
				Character.Humanoid.WalkToPoint = target.HumanoidRootPart.Position
				
			end
		end
		end
		
		end)
	

		
	
		
		if PlayersBattle.Value.Character:FindFirstChild('Humanoid') == false then if MovedEvents[PlayersBattle.Value] then MovedEvents[PlayersBattle.Value]:Disconnect() table.remove(MovedEvents,table.find(MovedEvents,PlayersBattle.Value)) end end
		if PlayersBattle.Value.Character:FindFirstChild('Humanoid').Health <= 0 then if MovedEvents[PlayersBattle.Value] then  MovedEvents[PlayersBattle.Value]:Disconnect() table.remove(MovedEvents,table.find(MovedEvents,PlayersBattle.Value)) end end
		
	end
	

	if Character and (Character:FindFirstChildOfClass("Humanoid") == nil or Character:FindFirstChildOfClass("Humanoid").Health > 0) then
		
		
		
		local AttackingThread
		
		local function CleanUp()
			AttackingThread = nil
			local IndexA = 1
			for Index,Connection in pairs(MovedEvents) do
				Connection:Disconnect()
				table.remove(MovedEvents,IndexA)
				IndexA += 1
			end
			
			
			return
			
		end

		AttackingThread = function()
			
		

			while true do


				local plrs = {}
				local c = Character.Players:GetChildren()
				for i=1,#c do
					table.insert(plrs,c[i].Value)
				end
				if target and target.Parent and target:FindFirstChild("HumanoidRootPart") then else end

				if true then
					local block = Instance.new("ObjectValue")
					block.Name = "_attacktag"
					block.Parent = Character
					game.Debris:AddItem(block,Info.Hitspeed)
					if not Info.AttackOrderRandom and target and target.Parent and target:FindFirstChild("HumanoidRootPart") then
						if order <= #Info.AttackOrder and target and target.Parent and target:FindFirstChild("HumanoidRootPart") then
							if string.sub(Info.AttackOrder[order],1,6) == "SERVER" then
								local attack = require(Character.Attacks:FindFirstChild(Info.AttackOrder[order]))
								attack(target)	
							else
								for i=1,#plrs do
									game.Lighting.AttackOnClient:FireClient(plrs[i],Character.Attacks:FindFirstChild(Info.AttackOrder[order]),target,Character)
								end	
							end				
							order = order + 1
						elseif target then
							order = 1 
							if string.sub(Info.AttackOrder[order],1,6) == "SERVER" then
								local attack = require(Character.Attacks:FindFirstChild(Info.AttackOrder[order]))
								attack(target)	
							else
								for i=1,#plrs do
									game.Lighting.AttackOnClient:FireClient(plrs[i],Character.Attacks:FindFirstChild(Info.AttackOrder[order]),target,Character)
								end	
							end				
						end
					elseif target and target.Parent and target:FindFirstChild("HumanoidRootPart") then
						if string.sub(Info.AttackOrder[order],1,6) == "SERVER" then
							local attack = require(Character.Attacks:FindFirstChild(Info.AttackOrder[order]))
							attack(target)	
						else
							for i=1,#plrs do
								game.Lighting.AttackOnClient:FireClient(plrs[i],Character.Attacks:FindFirstChild(Info.AttackOrder[order]),target,Character)
							end	
						end				
					end
				end

				if Character.Humanoid.Health <= 0 then CleanUp() break end
				wait(Info.Hitspeed)
			end


		end
		AttackingThread()
		
	end
	
end