-
What do you want to achieve? Keep it simple and clear!
I want this module run perfectly since it handle all ai, some damage module, some hitbox, some tools, some stored attacks without it breaking for no reason at random times, also theres no error output so i still can’t solve it -
What is the issue? Include screenshots / videos if possible!
The issue is as the title says, Runservice Heartbeat stopped for no reason at random times, Some AI just stand there when the service breaking for no reason and other attack inside it. You can see the code below. No screenshots or videos because theres no error output causing this, it only send the output if ActiveConnection already exist, which causing the stored stuff to stack and never run -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried printing method on the heartbeat to see how far it running and where it stop incase it break, but its useless when it break for no reason it just did one single iteration/frame fired/loop and stopped, I tried looking solutions on Dev Hub but theres no solved case and few of them only having this issue
It worked fine on studio and never break, but in game it just break at random time
Some attack tools cooldown handling, storing attacks, hitbox detection, damage module and all enemy AI fire this function below every time they are added to workspace
function CharStuffs:CheckConnection()
if ActiveConnection then
warn(ActiveConnection, "there already connection, Active attacks: " .. #ActiveAttacks .. ", Active CDs: " .. CountActiveCDs() .. ", Active Stored Attacks: " .. #StoreAttacks .. ", Active Store Loop DMG Modules: " .. #StoreLoopDMGAttacks .. ", Active NPC Tracking: " .. #StoreNPCTracking)
return
end
if not ActiveConnection then
ActiveConnection = RS.Heartbeat:Connect(function(t)
--print(ActiveConnection, t .. ", running the module loop, Active attacks: " .. #ActiveAttacks .. ", Active CDs: " .. CountActiveCDs() .. ", Active Stored Attacks: " .. #StoreAttacks .. ", Active Store Loop DMG Modules: " .. #StoreLoopDMGAttacks .. ", Active NPC Tracking: " .. #StoreNPCTracking)
if #ActiveAttacks <= 0 and CountActiveCDs() <= 0 and #StoreAttacks <= 0 and #StoreLoopDMGAttacks <= 0 and #StoreNPCTracking <= 0 then
if ActiveConnection then
ActiveConnection:Disconnect()
ActiveConnection = nil
warn(ActiveConnection, "Noooooo it end already, Active attacks: " .. #ActiveAttacks .. ", Active CDs: " .. CountActiveCDs() .. ", Active Stored Attacks: " .. #StoreAttacks .. ", Active Store Loop DMG Modules: " .. #StoreLoopDMGAttacks .. ", Active NPC Tracking: " .. #StoreNPCTracking)
if #ActiveAttacks > 0 or CountActiveCDs() > 0 or #StoreAttacks > 0 or #StoreLoopDMGAttacks > 0 or #StoreNPCTracking > 0 then
warn("There still remaining left")
CharStuffs:CheckConnection()
end
return
end
end
for PlrChar, TableValues in pairs(ActiveCDS) do
if not PlrChar or not PlrChar.Parent then
if ActiveCDS[PlrChar] then
ActiveCDS[PlrChar] = nil
end
continue
end
for TheInstance, ValueStuff in pairs(TableValues) do
if not PlrChar or not PlrChar.Parent then
if ActiveCDS[PlrChar] then
ActiveCDS[PlrChar] = nil
end
continue
end
if not TheInstance or not TheInstance.Parent then continue end
if ValueStuff[4] and ValueStuff[4] == true then continue end
if os.clock() - ValueStuff[3] > ValueStuff[2] then
if TheInstance then
if TheInstance:IsA("Tool") and TheInstance:GetAttribute("OGName") then
TheInstance.Name = TheInstance:GetAttribute("OGName")
TheInstance.Enabled = true
elseif TheInstance:IsA("TextButton") and TheInstance:GetAttribute("OGText") then
TheInstance.Text = TheInstance:GetAttribute("OGText")
if TheInstance:GetAttribute("OnCD") then
TheInstance:SetAttribute("OnCD", nil)
end
end
end
if PlrChar and ActiveCDS[PlrChar][TheInstance] then
ActiveCDS[PlrChar][TheInstance] = nil
elseif not PlrChar or not PlrChar.Parent then
if ActiveCDS[PlrChar] then
ActiveCDS[PlrChar] = nil
end
end
continue
end
if TheInstance and TheInstance:IsA("Tool") then
TheInstance.Name = math.round((ValueStuff[2] - (os.clock() - ValueStuff[3])) * 10) / 10
elseif TheInstance and TheInstance:IsA("TextButton") then
TheInstance.Text = math.round((ValueStuff[2] - (os.clock() - ValueStuff[3])) * 10) / 10
end
end
end
for k, v in pairs(ActiveAttacks) do
if not v[1] or not v[1].Parent or not v[2] or not v[3] or not v[4] or not v[4].Parent or not v[5] or not v[5].Parent then
-- warn(k, v[1], v[1].Parent, v[2], v[3], v[4], v[4].Parent, v[5], v[5].Parent, v, " Nil values ", "-- Line 137")
if v[1] then
v[1]:Destroy()
end
if v[5] then
v[5]:Destroy()
end
table.remove(ActiveAttacks, k)
continue
end
local AttackParams = AttackParamsModule:ReturnTheParams()
local DMG, DB = v[2]["DMG"] or 0 , v[2]["Debounce"] or 0.1
local GetTheHitbox
if v[2]["HitboxType"] and v[2]["HitboxType"] == "Box" then
local CFrameOffsets, TheSizeMultiplier, TheSizeIncrease = v[2]["CFrameOffsets"] or CFrame.new(0, 0, 0) , v[2]["SizeMultiplier"] or 1 , v[2]["SizeIncrease"] or Vector3.zero
GetTheHitbox = workspace:GetPartBoundsInBox(v[5].CFrame * CFrameOffsets, (v[5].Size * TheSizeMultiplier) + TheSizeIncrease, AttackParams)
elseif v[2]["HitboxType"] and v[2]["HitboxType"] == "Radius" then
local PosOffsets, TheSizeMultiplier, TheSizeIncrease = v[2]["PositionOffsets"] or Vector3.zero , v[2]["SizeMultiplier"] or 1 , v[2]["SizeIncrease"] or 0
GetTheHitbox = workspace:GetPartBoundsInRadius(v[5].Position + PosOffsets, ((v[5].Size.X * TheSizeMultiplier) + TheSizeIncrease) / 2, AttackParams)
end
if v[1] and v[1]:GetAttribute("ExtraDMG") then
DMG += v[1]:GetAttribute("ExtraDMG")
end
if not GetTheHitbox then warn("No Hitbox. Line 164") continue end
for __, h in pairs(GetTheHitbox) do
if not h or not h.Parent then continue end
if v["PausedAttack"] then continue end
if not h.Parent:FindFirstChildOfClass("Humanoid") or h.Parent:FindFirstChildOfClass("Humanoid").Health <= 0 then continue end
if not h.Parent:FindFirstChild("HumanoidRootPart") or not h.Parent:FindFirstChild("Torso") then continue end
if table.find(v[3], h.Parent) then continue end
if not v[4] or not v[4].Parent then continue end
table.insert(v[3], h.Parent)
if DB then
task.delay(DB, function()
if not h or not h.Parent or not table.find(v[3], h.Parent) then return end
table.remove(v[3], table.find(v[3], h.Parent))
end)
end
local TheChar:Model = h.Parent
local TheHumRoot:Part = TheChar:FindFirstChild("HumanoidRootPart")
local TheTorso:Part = TheChar:FindFirstChild("Torso")
local TheHumanoid:Humanoid = TheChar:FindFirstChildOfClass("Humanoid")
if v["PausedAttack"] then continue end
local TakeDMG = GeneralModule:TakeDamage(nil, v[4], TheChar, {DMG})
if TakeDMG and tonumber(TakeDMG) then
if v[2]["CustomEffect"] and typeof(v[2]["CustomEffect"]) == "function" then
v[2]["CustomEffect"](TheChar)
end
end
end
if v[1]:FindFirstChild("CustomFunction") then
require(v[1]:FindFirstChild("CustomFunction")):Function(t)
end
end
for k, v in pairs(StoreAttacks) do
if not v["ThePlayer"] or not v["ThePlayer"].Parent or not v["TheAttack"] or not v["TheAttack"].Parent then
if v["TheAttack"] then
v["TheAttack"]:Destroy()
end
table.remove(StoreAttacks, k)
continue
end
-- print(v["DestroyIfCharNil"], v["ThePlayerCharacter"], v["ThePlayerCharacter"].Parent)
if v["DestroyIfCharNil"] and (not v["ThePlayerCharacter"] or not v["ThePlayerCharacter"].Parent) then
if v["TheAttack"] then
v["TheAttack"]:Destroy()
end
table.remove(StoreAttacks, k)
continue
end
if v["DestroyIfCharNil2"] and v["ThePlayer"] and v["ThePlayer"].Parent and v["TheTool"] then
if not CharStuffs:CheckConditions(v["ThePlayer"], v["TheTool"]) then
if v["TheAttack"] then
v["TheAttack"]:Destroy()
end
table.remove(StoreAttacks, k)
continue
end
end
end
for k, v in pairs(StoreLoopDMGAttacks) do
if not v[1] or not v[1].Parent or not v[2] or not v[2].Parent or not v[3] or not v[3].Parent then
--warn(v[1], v[1].Parent, v[2], v[2].Parent, v[3], v[3].Parent, " Nil values idk, Line 228")
if v[2] then
v[2]:Destroy()
end
table.remove(StoreLoopDMGAttacks, k)
continue
end
require(v[3]):DamageThem(t)
end
for k, v in pairs(StoreNPCTracking) do
if not v[1] or not v[1].Parent or
not v[1]:FindFirstChild("HumanoidRootPart") or not v[1]:FindFirstChild("HumanoidRootPart").Parent or
not v[1]:FindFirstChild("Torso") or not v[1]:FindFirstChild("Torso").Parent or
not v[1]:FindFirstChildOfClass("Humanoid") or not v[1]:FindFirstChildOfClass("Humanoid").Parent or
v[1]:FindFirstChildOfClass("Humanoid").Health <= 0 or
v[1]:FindFirstChildOfClass("Humanoid"):GetState() == Enum.HumanoidStateType.Dead then
table.remove(StoreNPCTracking, k)
continue
end
if v[1]:GetAttribute("PauseTracking") then continue end
TrackingTime(v[1])
end
-- print(ActiveConnection, t .. ", end run of module loop, Active attacks: " .. #ActiveAttacks .. ", Active CDs: " .. CountActiveCDs() .. ", Active Stored Attacks: " .. #StoreAttacks .. ", Active Store Loop DMG Modules: " .. #StoreLoopDMGAttacks .. ", Active NPC Tracking: " .. #StoreNPCTracking)
end)
end
end
Any suggestion is appreciated!