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
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.
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.
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?
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
I see a lot of loops indeed, could you use coroutine if possible?
Possibly, would it be better just to rewrite this code with coroutine?
If you wanna. I would recommend avoiding as many loops because from what’ve seen you call a for loop on every while true. Even better try to organize your workspace so you don’t have to use workspace:GetChildren()
, and if you wanna get players just use this.
local function FindTarget()
local dist = Info.RangeofVision
local found = nil
for _,v in game:GetService("Players"):GetPlayers() do
local Victim = v.Character
if Victim and Victim:FindFirstChild("HumanoidRootPart") and Victim:FindFirstChildOfClass("Humanoid").Health > 0 and Victim:FindFirstChild("_enemytag") == nil and Victim ~= Character and (Character.HumanoidRootPart.Position - Victim.HumanoidRootPart.Position).Magnitude <= dist then
dist = (Character.HumanoidRootPart.Position - Victim.HumanoidRootPart.Position).Magnitude
found = Victim
end
end
target = found
end