Hey im trying to reduce spiking in my npcs I dont know why its spiking so much I think its because I set it up so all my NPCS in one heartbeat and that may be creating lag?
Things to note
- all my npcs physics are turned off
local Tab = {
Chase = function(NPC,Target,Tags,Data)
local root = NPC.HumanoidRootPart
local enemy = Target.Value
local ehum = enemy:FindFirstChild("Humanoid")
local eroot = enemy:FindFirstChild("HumanoidRootPart")
local pos = eroot.Position
if not ActionCheck(Tags) then
if math.random(1, 3) == 1 and ((root.Position - eroot.Position).magnitude > 15) and Data.Type ~= "Robot" then
return combatModule.DashNPC(NPC, "Front")
end
if Data.Type ~= "Robot" then
combatModule.Run(NPC)
NPCModule:MoveTo(NPC, pos, Data, enemy, true)
else
if not Data.FirstChase then
Data.FirstChase = true
Data.FirstMag = (root.Position - eroot.Position).magnitude
end
local Run = Data.LoadedAnims.Run
if math.random(1,45) == 1 and os.clock() - Data.LastCool > 15 and (root.Position - eroot.Position).magnitude < 50 then
Data.LastCool = os.clock()
local Action = create("Action",nil,Data.Tags)
Run:Stop()
local Laser = Data.LoadedAnims.Laser
Laser:Play()
NPC.Humanoid.WalkSpeed = 0
task.wait(.35)
game:GetService("TweenService"):Create(NPC["Cube.007"],TweenInfo.new(.50,Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {Color = Color3.fromRGB(255,255,255)}):Play()
task.wait(.30)
game:GetService("TweenService"):Create(NPC["Cube.007"],TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {Color = Color3.fromRGB(255,0,0)}):Play()
Laser.Stopped:Wait()
game:GetService("TweenService"):Create(NPC["Cube.007"],TweenInfo.new(1,Enum.EasingStyle.Sine,Enum.EasingDirection.Out), {Color = Color3.fromRGB(0,0,0)}):Play()
NPC.Humanoid.WalkSpeed = 10
Action:Destroy()
return
end
if not Run.IsPlaying and not ActionCheck(Tags) then
Run:Play()
Run:GetMarkerReachedSignal("Step"):Connect(function()
coroutine.wrap(function()
for i,v in pairs(game.Workspace.World.Live:GetChildren()) do
if v:IsA("Model") and v:FindFirstChild("Humanoid") and (v:FindFirstChild("HumanoidRootPart")) and game.Players:FindFirstChild(v.Name) and (v:FindFirstChild("HumanoidRootPart").Position - root.Position).Magnitude <= 250 then
local TargetPlayer = game.Players:GetPlayerFromCharacter(v)
if not Data.FirstChase[v.Name] then
Data.FirstChase[v.Name] = true
Data.FirstMag[v.Name] = (root.Position - v:FindFirstChild("HumanoidRootPart").Position).magnitude
end
if not Data.shakecool[v.Name] then
Data.shakecool[v.Name] = true
VisualEvent:FireClient(TargetPlayer,"CameraShake",10,v,root,true,Data.FirstMag[v.Name])
task.wait()
Data.shakecool[v.Name] = nil
end
end
end
end)()
end)
end
NPCModule:MoveTo(NPC, pos, Data, enemy, true)
end
end
return
end,
Block = function(NPC,Target,Tags,Data)
Data.FirstChase = {}
Data.FirstMag = {}
if ActionCheck(Tags) or Data.Type == "Robot" then
return
end
local root = NPC:FindFirstChild("HumanoidRootPart")
local enemy = Target.Value
local eroot = enemy:FindFirstChild("HumanoidRootPart")
local pos = eroot.Position
combatModule.Block(NPC)
combatModule.RunStop(NPC)
local amount = 10
local timer = os.clock()
while true do
if ActionCheck2(Tags) then
break
end
if not enemy.Parent or not Tags:FindFirstChild("Attacking") then
break
end
if Target.Value ~= enemy then
break
end
NPCModule:MoveTo(NPC, pos - CFrame.new(root.Position, pos).LookVector * amount, NPCData[NPC.Name])
amount = amount + 1
task.wait(2)
end
timer = os.clock()
while os.clock() - timer < 0.4 do
if ActionCheck2(Tags) then
break
end
task.wait(0)
end
combatModule.BlockStop(NPC)
create("NoBlock", 1, Tags)
create("NoSwing", 0.2, Tags)
return
end,
Standby = function(NPC,Target,Tags, Data)
Data.FirstChase = {}
Data.FirstMag = {}
local enemy = _G.TargetedBy[Target.Value]
local root = NPC.HumanoidRootPart
if enemy and Data.Type ~= "Robot" then
local eroot = enemy:FindFirstChild("HumanoidRootPart")
local pos = eroot.Position
local neg = math.random(15,30)
local pos2 = math.random(15,30)
local distance = math.random(1, 2) == 2 and -neg or pos2
local pos2 = pos - CFrame.new(root.Position, pos).RightVector * distance
local sideHit = workspace:FindPartOnRayWithIgnoreList(Ray.new(pos2, CFrame.new(pos2).UpVector * -100), {workspace.World.Live, workspace.World.MouseFilter.Visuals})
combatModule.RunStop(NPC)
if (os.clock() - NPCData[NPC.Name]["LAST_STRAFE"] > 0.5) then
NPCData[NPC.Name]["LAST_STRAFE"] = os.clock()
NPCModule:MoveTo(NPC, pos2, NPCData[NPC.Name])
end
elseif enemy and Data.Type == "Robot" then
end
return
end,
Evade = function(NPC, Target, Tags, Data)
Data.FirstChase = {}
Data.FirstMag = {}
local root = NPC.HumanoidRootPart
local enemy = Target.Value
local eroot = enemy:FindFirstChild("HumanoidRootPart")
local pos = eroot.Position
combatModule.RunStop(NPC)
if math.random(1,3) == 1 then
combatModule.Dodge(NPC)
else
NPCModule:MoveTo(NPCData[NPC.Name], pos - CFrame.new(root.Position, pos).LookVector * 50, NPCData[NPC.Name])
end
return
end,
Fight = function(NPC, Target, Tags, Data)
Data.FirstChase = {}
Data.FirstMag = {}
local enemy = Target.Value
local targetedBy = _G.TargetedBy[enemy]
if targetedBy and targetedBy ~= NPC and not Data.EnemyTags:FindFirstChild("IsAMonster") then
return
end
local root = NPC.HumanoidRootPart
if Data.Type == "Robot" then return end
local eroot = enemy:FindFirstChild("HumanoidRootPart")
local distance = math.random(1, 2) == 2 and -5 or 5
local pos = eroot.Position
combatModule.RunStop(NPC)
if Data.can_strafe and not ActionCheck(Data.Tags) then
pos = eroot.Position
local pos2 = pos - CFrame.new(root.Position, pos).RightVector * distance
local sideHit = workspace:FindPartOnRayWithIgnoreList(Ray.new(pos2, CFrame.new(pos2).UpVector * -100), {workspace.World.Live, workspace.World.MouseFilter.Visuals})
elseif os.clock() - Data.LastEvade > Data.ATTEMPTNUM then
Data.LastEvade = os.clock()
if math.random(1, 5) <= 3 then
Data.ATTEMPTNUM = 1.5
if distance > 0 then
combatModule.DashNPC(NPC, "Right")
else
combatModule.DashNPC(NPC, "Left")
end
else
Data.ATTEMPTNUM = 2
end
end
if (root.Position - eroot.Position).magnitude > 8 or (Data.strafing and Tags:FindFirstChild("NoSwing")) then
return
end
if (Data.UserAsign.Block.Active or math.random(1, 5) >= 3) and not Tags:FindFirstChild("NoHeavy") then
combatModule.Heavy(NPC)
else
combatModule.Attack(NPC)
end
return
end,
}
game:GetService("RunService").Heartbeat:Connect(function()
for NPC, bool in pairs(TotalNPCS) do
coroutine.wrap(function()
if not NPC:FindFirstChild("Humanoid") then
NPCData[NPC.Name] = nil
TotalNPCS[NPC] = false
return
end
local humanoid = NPC:FindFirstChild("Humanoid")
local Data = NPCData[NPC.Name]
local root = NPC:FindFirstChild("HumanoidRootPart")
if not Data or not root or not humanoid then
NPCData[NPC.Name] = nil
TotalNPCS[NPC] = false
return
end
if Data.Tags:FindFirstChild("Gripping") or Data.Tags:FindFirstChild("BeingGripped") or Data.Tags:FindFirstChild("BeingCarried") or Data.Tags:FindFirstChild("DeadKnocked") then
Data.last_target = os.clock()
end
if os.clock() - Data.last_target > 60 then
NPC:Destroy()
return
end
if humanoid.Health <= 1 or not NPC.Parent then
for a, b in pairs(_G.TargetedBy) do
if b == NPC then
_G.TargetedBy[a] = nil
end
end
Data.Target.Value = nil
return
end
if not Data.Tags:FindFirstChild("Carried") then
setNetworkOwnerOfModel(NPC, nil)
humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
end
if Data.Tags:FindFirstChild("NoFunction") then
return
end
if Data.Target.Value and (not Data.Target.Value:FindFirstChild("Humanoid") or Data.Target.Value.Humanoid.health <= 1) and not Data.Target.Value.Parent and not Data.EnemyTags:FindFirstChild("BeingGripped") and not Data.Target.Value:FindFirstChild("HumanoidRootPart") then
Data.Target.Value = nil
end
Data.Target.Value = findTarget(NPC, root, Data.State)
if Data.Target.Value then
Data.EnemyAsign = GeneralAsign.GetAsign(Data.Target.Value)
if Data.EnemyAsign == nil then
Data.EnemyAsign = GeneralAsign.CreateAsign(Data.Target.Value.Name)
Data.EnemyState = game.ReplicatedStorage.PlayerStates[Data.Target.Value.Name]
Data.EnemyTags = Data.EnemyState.Tags
end
Data.EnemyState = game.ReplicatedStorage.PlayerStates[Data.Target.Value.Name]
Data.EnemyTags = Data.EnemyState.Tags
Data.last_target = os.clock()
local enemy = Data.Target.Value
local ehum = enemy:FindFirstChild("Humanoid")
local eroot = enemy:FindFirstChild("HumanoidRootPart")
local Attacking = Data.EnemyTags:FindFirstChild("Attacking")
if Data.Type == "Robot" then
local magnitude = (root.Position - eroot.Position).magnitude
if magnitude > 600 then
Data.Target.Value = nil
Data.State = "Wander"
return
end
if magnitude > 30 then
Data.State = "Chase"
elseif magnitude < 30 then
if not _G.TargetedBy[enemy] then
_G.TargetedBy[enemy] = NPC
end
Data.State = "Fight"
end
else
local magnitude = (root.Position - eroot.Position).magnitude
if magnitude > 200 then
Data.Target.Value = nil
Data.State = "Wander"
return
end
if magnitude > 5 then
Data.State = "Chase"
elseif magnitude < 5 then
if not _G.TargetedBy[enemy] then
_G.TargetedBy[enemy] = NPC
end
if Data.EnemyTags:FindFirstChild("Attacking") and math.random(1,2) == 1 then
Data.State = "Block"
else
Data.State = "Fight"
end
if Data.Tags:FindFirstChild("Stunned") and Data.Type ~= "Robot" then
Data.State = "Evade"
end
end
end
local TargetedBy = _G.TargetedBy[enemy]
if TargetedBy and TargetedBy ~= NPC then
if isAlly(NPC, TargetedBy) and ((TargetedBy.HumanoidRootPart.Position - eroot.Position).magnitude < 10 or TargetedBy:FindFirstChild("Attacking")) then
if not enemy:FindFirstChild("IsAMonster") then
Data.State = "Standby"
end
else
_G.TargetedBy[enemy] = NPC
create("NoSwing", 0.5, Data.Tags)
end
local root = NPC.HumanoidRootPart
local Possible = findTarget(NPC, root, Data.State)
if Possible ~= nil and Possible ~= enemy then
Data.Target.Value = Possible
return
end
end
if Data.EnemyTags:FindFirstChild("DeadKnocked") and Data.Type ~= "Robot" then
if Data.Tags:FindFirstChild("Gripping") or Data.Tags:FindFirstChild("Arresting") then
Data.Target.Value = nil
Data.State = "Wander"
else
if not Data.EnemyTags:FindFirstChild("BeingGripped") and not Data.EnemyTags:FindFirstChild("BeingArrested") then
Data.State = "Execute"
else
Data.Target.Value = nil
Data.State = "Wander"
end
end
end
else
Data.State = "Wander"
end
return Tab[Data.State](NPC,Data.Target,Data.Tags, Data)
end)()
end
end)
game.ServerStorage.Bindables.setNPC.Event:Connect(function(NPC)
NPCModule:SetupNPC(NPC)
end)