-- ═══════════════════════════════════════════════════════════════════════════════ -- SCP-096 SL - STRICT STATE MACHINE AI (SMART PATHFINDING, MULTI-TAB) -- ═══════════════════════════════════════════════════════════════════════════════ if getgenv().SCP096_GUI then pcall(function() getgenv().SCP096_GUI:Destroy() end) end getgenv().SCP096_GUI = nil local VirtualInputManager = game:GetService("VirtualInputManager") local Players = game:GetService("Players") local SoundService = game:GetService("SoundService") local Workspace = game:GetService("Workspace") local RunService = game:GetService("RunService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local ReplicatedFirst = game:GetService("ReplicatedFirst") local PathfindingService = game:GetService("PathfindingService") local Teams = game:GetService("Teams") local LocalPlayer = Players.LocalPlayer -- UI Library Setup local Library = nil local uiLoadSuccess = pcall(function() Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/xHeptc/Kavo-UI-Library/main/source.lua"))() end) if not uiLoadSuccess or not Library then Library = { CreateLib = function() local ScreenGui = Instance.new("ScreenGui") ScreenGui.Name = "SCP096FallbackGUI" ScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui") getgenv().SCP096_GUI = ScreenGui local function createSection(frame) return { NewToggle = function(self, text, desc, callback) local toggle = Instance.new("TextButton") toggle.Size = UDim2.new(1, 0, 0, 30) toggle.Text = text .. " (off)" toggle.BackgroundColor3 = Color3.fromRGB(50,50,50) toggle.Parent = frame local state = false toggle.MouseButton1Click:Connect(function() state = not state toggle.Text = text .. (state and " (on)" or " (off)") callback(state) end) end, NewButton = function(self, text, desc, callback) local btn = Instance.new("TextButton") btn.Size = UDim2.new(1, 0, 0, 30) btn.Text = text btn.BackgroundColor3 = Color3.fromRGB(0,100,200) btn.Parent = frame btn.MouseButton1Click:Connect(callback) end } end return { NewTab = function(self, name) local frame = Instance.new("ScrollingFrame") frame.Size = UDim2.new(0, 220, 0, 260) frame.Position = UDim2.new(0, 10 + (#ScreenGui:GetChildren() * 230), 0, 100) frame.BackgroundColor3 = Color3.fromRGB(30,30,30) frame.Name = name frame.Parent = ScreenGui local title = Instance.new("TextLabel") title.Size = UDim2.new(1, 0, 0, 20) title.Text = name title.TextColor3 = Color3.new(1,1,1) title.BackgroundTransparency = 1 title.Parent = frame local listLayout = Instance.new("UIListLayout") listLayout.Parent = frame listLayout.SortOrder = Enum.SortOrder.LayoutOrder return { NewSection = function() return createSection(frame) end } end } end } end local Window = Library.CreateLib("SCP-096 SL", "DarkTheme") local TabControl = Window:NewTab("Control") local TabTeleports = Window:NewTab("Teleports & Teams") local TabNPCKill = Window:NewTab("NPC Loop Kill") local SecControl = TabControl:NewSection("SCP-096 State Machine") local SecTeleports = TabTeleports:NewSection("Utility") local SecNPCKill = TabNPCKill:NewSection("Fast Loop Kill") -- Configuration & State Definitions local BUBBLE_RADIUS = 4.0 local KILL_DISTANCE = 4.0 local RUN_START_DELAY = 1.2 local MIN_CHASE_DURATION = 4.0 local KILL_ANIMATION_DURATION = 4.0 local HEALTH_MAX = 3000 local CRITICAL_CHANCE = 10 local KILL_COOLDOWN = 1.0 local SUPER_FAR_DISTANCE = 300 local RUN_TOOL = "096 - Run" local IDLE_TOOL = "096 - Idle" local KILL_TOOL = "096 - Kill" local currentState = "IDLE" local aiEnabled = false local manualModeEnabled = false local npcTestingEnabled = false local showBubble = false local fastNpcLoopKillEnabled = false local currentTarget = nil local stateStartTime = 0 local chaseStartTime = 0 local touchConnection = nil local bubblePart = nil local isKillingActive = false local lastScanTime = 0 local lastKillEndTime = 0 local lastPathTime = 0 -- Smooth Pathfinding Variables local lastTargetPos = nil local currentWaypoints = nil local currentWaypointIndex = 1 -- Emote & Notice Variables local hasTriggeredNotice = false local tPoseTrack = nil -- Client-Side (FE bypass inside self) Audio Setup local function createLocalSound(name, id) local sound = Instance.new("Sound") sound.Name = name sound.SoundId = id sound.Volume = 1.5 sound.Looped = true sound.Parent = SoundService return sound end local IdleSound = createLocalSound("IdleSound", "rbxassetid://491877423") local NoticeSound = createLocalSound("NoticeSound", "rbxassetid://491877470") local ScreamingSound = createLocalSound("ScreamingSound", "rbxassetid://491877546") NoticeSound.Looped = false -- Audio Utils local function getSoundParent() local char = LocalPlayer.Character if not char then return SoundService end return char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Head") or SoundService end -- Synchronized Dual Kill Audio local function playSyncKillAudioFE() local parent = getSoundParent() local sound1 = Instance.new("Sound") sound1.SoundId = "rbxassetid://531421188" sound1.Volume = 1.5 sound1.Parent = parent local sound2 = Instance.new("Sound") sound2.SoundId = "rbxassetid://17878427121" sound2.Volume = 1.5 sound2.Parent = parent sound1:Play() sound2:Play() sound1.Ended:Connect(function() sound1:Destroy() end) sound2.Ended:Connect(function() sound2:Destroy() end) end -- Input Utils local function autoClickScreen() local char = LocalPlayer.Character if char then for _, tool in ipairs(char:GetChildren()) do if tool:IsA("Tool") then tool:Activate() end end end pcall(function() local cam = Workspace.CurrentCamera if cam then local center = cam.ViewportSize / 2 VirtualInputManager:SendMouseButtonEvent(center.X, center.Y, 0, true, game, 0) task.wait(0.05) VirtualInputManager:SendMouseButtonEvent(center.X, center.Y, 0, false, game, 0) end end) end -- Tools & Animation Utils local function getTool(name) local char = LocalPlayer.Character if char and char:FindFirstChild(name) then return char:FindFirstChild(name) end local backpack = LocalPlayer:FindFirstChild("Backpack") return backpack and backpack:FindFirstChild(name) end local function equipTool(name) local tool = getTool(name) local humanoid = LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass("Humanoid") if tool and humanoid and tool.Parent ~= LocalPlayer.Character then humanoid:EquipTool(tool) end end local function unequipAllToolsFast() local humanoid = LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass("Humanoid") if humanoid then humanoid:UnequipTools() end end local function isToolEquipped(name) local char = LocalPlayer.Character return char and char:FindFirstChild(name) ~= nil end -- T-Pose Emote Logic local function playTPoseEmote() local character = LocalPlayer.Character local humanoid = character and character:FindFirstChildOfClass("Humanoid") if not humanoid then return end local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid) local anim = Instance.new("Animation") anim.AnimationId = "rbxassetid://116099256350648" tPoseTrack = animator:LoadAnimation(anim) tPoseTrack.Priority = Enum.AnimationPriority.Action tPoseTrack:Play() if not IdleSound.IsPlaying then IdleSound:Play() end end local currentAnimTrack = nil local function playKillAnimation() local character = LocalPlayer.Character local humanoid = character and character:FindFirstChildOfClass("Humanoid") if not humanoid then return nil end local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid) local anim = Instance.new("Animation") -- Updated to new Classic SCP 096 Kill Animation anim.AnimationId = "rbxassetid://15172539171" local success, track = pcall(function() return animator:LoadAnimation(anim) end) if success and track then if currentAnimTrack then currentAnimTrack:Stop() end currentAnimTrack = track track.Priority = Enum.AnimationPriority.Action4 track:Play(0.1, 1, 1.0) return track end return nil end local function calculateDamage() return math.random(1, 100) <= CRITICAL_CHANCE and (10^30 + 10^18) or 500 end local function executeKillTarget(targetHum) if not targetHum or targetHum.Health <= 0 then return end local damage = calculateDamage() local shotgun = getTool("Shotgun") if shotgun and shotgun:FindFirstChild("Receiver") then shotgun.Receiver:FireServer("Damage", targetHum, damage) else targetHum.Health = 0 end end -- State Transitions local function transitionToIdle() currentState = "IDLE" currentTarget = nil isKillingActive = false unequipAllToolsFast() equipTool(IDLE_TOOL) lastKillEndTime = os.clock() if ScreamingSound.IsPlaying then ScreamingSound:Stop() end if not IdleSound.IsPlaying then IdleSound:Play() end -- Reset pathfinding smoothing variables lastTargetPos = nil currentWaypoints = nil task.spawn(function() task.wait(0.15) if currentState == "IDLE" then autoClickScreen() end end) end local function doTeleport() local block = Workspace:FindFirstChild("Block") if block then local parts = block:GetChildren() if parts[198] and LocalPlayer.Character then local targetPart = parts[198] local lookVector = targetPart.CFrame.LookVector LocalPlayer.Character:PivotTo(CFrame.new(targetPart.Position, targetPart.Position + lookVector)) end end transitionToIdle() end local function transitionToRunStart(targetModel) if currentState ~= "IDLE" or not targetModel then return end if os.clock() - lastKillEndTime < KILL_COOLDOWN then return end currentState = "RUN_START" currentTarget = targetModel stateStartTime = os.clock() unequipAllToolsFast() equipTool(RUN_TOOL) IdleSound:Stop() if not ScreamingSound.IsPlaying then ScreamingSound:Play() end task.spawn(function() task.wait(0.15) if currentState == "RUN_START" or currentState == "CHASE" then autoClickScreen() end end) end local function transitionToChase() if currentState ~= "RUN_START" then return end currentState = "CHASE" chaseStartTime = os.clock() end local function transitionToKill(targetHumanoid) if currentState ~= "CHASE" or isKillingActive or not targetHumanoid then return end currentState = "KILL" isKillingActive = true unequipAllToolsFast() equipTool(KILL_TOOL) playSyncKillAudioFE() -- Mute Screaming audio during kill animation ScreamingSound.Volume = 0 local track = playKillAnimation() local isPlayer = Players:GetPlayerFromCharacter(targetHumanoid.Parent) ~= nil task.spawn(function() local startTime = os.clock() if not isPlayer then if track then track:AdjustSpeed(10) end local godModeTriggered = false while targetHumanoid and targetHumanoid.Parent and targetHumanoid.Health > 0 do executeKillTarget(targetHumanoid) if os.clock() - startTime > 2.0 and not godModeTriggered then godModeTriggered = true if track then track:Stop() end local hum = LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass("Humanoid") if hum then for _, playingTrack in ipairs(hum:GetPlayingAnimationTracks()) do playingTrack:Stop() end end end task.wait(0.1) end else local animDuration = (track and track.Length > 0) and track.Length or KILL_ANIMATION_DURATION while (os.clock() - startTime < animDuration) do if targetHumanoid and targetHumanoid.Parent and targetHumanoid.Health > 0 then executeKillTarget(targetHumanoid) end task.wait(0.15) end end if track then track:Stop() end -- Restore Screaming audio volume and go Idle, stopping chase ScreamingSound.Volume = 1.5 transitionToIdle() end) end -- Invisible Kill Tool local function giveCustomKillTool() local backpack = LocalPlayer:FindFirstChild("Backpack") or (LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("Backpack")) if not backpack then return end local oldTool = backpack:FindFirstChild(KILL_TOOL) or (LocalPlayer.Character and LocalPlayer.Character:FindFirstChild(KILL_TOOL)) if oldTool then oldTool:Destroy() end local killTool = Instance.new("Tool") killTool.Name = KILL_TOOL killTool.RequiresHandle = true killTool.CanBeDropped = false killTool.Parent = backpack local handle = Instance.new("Part") handle.Name = "Handle" handle.Size = Vector3.new(1, 1, 1) handle.Transparency = 1 handle.CanCollide = false handle.Parent = killTool end -- Touch Detection (Includes Fixed Manual Touch Kill) local function setupTouchListener() if touchConnection then touchConnection:Disconnect() end local char = LocalPlayer.Character if not char then return end local root = char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Torso") if not root then return end touchConnection = root.Touched:Connect(function(hit) local hitModel = hit.Parent if not hitModel or hitModel == char then return end local pHum = hitModel:FindFirstChildOfClass("Humanoid") if not pHum or pHum.Health <= 0 then return end if manualModeEnabled and isToolEquipped(KILL_TOOL) and not isKillingActive then if os.clock() - lastKillEndTime < KILL_COOLDOWN then return end isKillingActive = true playSyncKillAudioFE() ScreamingSound.Volume = 0 local track = playKillAnimation() local animDuration = (track and track.Length > 0) and track.Length or KILL_ANIMATION_DURATION task.spawn(function() local startTime = os.clock() while (os.clock() - startTime < animDuration) do executeKillTarget(pHum) task.wait(0.15) end if track then track:Stop() end isKillingActive = false lastKillEndTime = os.clock() ScreamingSound.Volume = 1.5 end) elseif aiEnabled and currentState == "IDLE" then if os.clock() - lastKillEndTime < KILL_COOLDOWN then return end local isPlayer = Players:GetPlayerFromCharacter(hitModel) ~= nil if not npcTestingEnabled or not isPlayer then transitionToRunStart(hitModel) end end end) end -- Initialization & Respawn LocalPlayer.CharacterAdded:Connect(function(newChar) task.wait(0.5) setupTouchListener() playTPoseEmote() end) if LocalPlayer.Character then setupTouchListener() playTPoseEmote() end -- UI: Tab 1 - Control SecControl:NewButton("Get shotgun", "Teleport to shotgun and equip", function() if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then LocalPlayer.Character:PivotTo(CFrame.new(-789.93, 3.0, 27.41)) task.wait(0.1) VirtualInputManager:SendKeyEvent(true, Enum.KeyCode.E, false, game) task.wait(0.05) VirtualInputManager:SendKeyEvent(false, Enum.KeyCode.E, false, game) end end) SecControl:NewButton("Give custom 096 - Kill", "Creates invisible kill tool", giveCustomKillTool) SecControl:NewToggle("Act like 096 (State Machine AI)", "Strict sequence AI", function(state) aiEnabled = state manualModeEnabled = false; npcTestingEnabled = false transitionToIdle() if state and not getTool(KILL_TOOL) then giveCustomKillTool() end end) SecControl:NewToggle("Manual Control", "Touch-kill only works when 096 - Kill is equipped", function(state) manualModeEnabled = state if state then aiEnabled = false; npcTestingEnabled = false; currentTarget = nil end end) SecControl:NewToggle("Show Bubble", "Display 4.0 stud detection bubble", function(state) showBubble = state if not state and bubblePart then bubblePart:Destroy(); bubblePart = nil end end) -- UI: Tab 2 - Teleports & Teams SecTeleports:NewButton("FE Custom Team (Scp096Sl)", "Creates & joins team so you take gun damage", function() local team = Teams:FindFirstChild("Scp096Sl") if not team then team = Instance.new("Team") team.Name = "Scp096Sl" team.TeamColor = BrickColor.new("Really red") team.AutoAssignable = false team.Parent = Teams end LocalPlayer.Team = team end) SecTeleports:NewButton("FE Name Tag Remover", "Removes Billboard/SurfaceGuis and DisplayNames", function() local char = LocalPlayer.Character if not char then return end for _, v in ipairs(char:GetDescendants()) do if v:IsA("BillboardGui") or v:IsA("SurfaceGui") then v.Enabled = false; v:Destroy() end end local hum = char:FindFirstChildOfClass("Humanoid") if hum then hum.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None end end) SecTeleports:NewButton("Teleport to Place Manually", "Teleports to block 198, resets chases", doTeleport) -- UI: Tab 3 - NPC Kill SecNPCKill:NewToggle("Fast Loop Kill NPC", "Instantly loops shotgun damage on SCP 096SL without lag/sound", function(state) fastNpcLoopKillEnabled = state end) -- Background Loops -- 1. Fast NPC Loop Kill task.spawn(function() while task.wait() do if fastNpcLoopKillEnabled then local target = Workspace:FindFirstChild("SCP 096SL") if target then local tHum = target:FindFirstChildOfClass("Humanoid") if tHum and tHum.Health > 0 then local shotgun = getTool("Shotgun") if shotgun and shotgun:FindFirstChild("Receiver") then shotgun.Receiver:FireServer("Damage", tHum, 10^30) end end end end end end) -- 2. NPC Ignore & Fast Regen (God Mode) task.spawn(function() while task.wait(0.1) do local char = LocalPlayer.Character if char then local hum = char:FindFirstChildOfClass("Humanoid") if hum then hum.MaxHealth = 3000 if hum.Health < 3000 then hum.Health = 3000 end end -- Clear player tags so NPCs ignore the user local pTag = char:FindFirstChild("Player") or char:FindFirstChild("TargetTag") if pTag then pTag:Destroy() end end end end) -- Main State Machine Loop RunService.RenderStepped:Connect(function() local char = LocalPlayer.Character local humanoid = char and char:FindFirstChildOfClass("Humanoid") local root = char and char:FindFirstChild("HumanoidRootPart") if showBubble then if not bubblePart then bubblePart = Instance.new("Part") bubblePart.Shape = Enum.PartType.Ball; bubblePart.Size = Vector3.new(BUBBLE_RADIUS*2, BUBBLE_RADIUS*2, BUBBLE_RADIUS*2) bubblePart.Transparency = 0.7; bubblePart.Anchored = true; bubblePart.CanCollide = false bubblePart.Material = Enum.Material.ForceField; bubblePart.BrickColor = BrickColor.new("Cyan") bubblePart.Parent = Workspace bubblePart.Touched:Connect(function(hit) if not aiEnabled or currentState ~= "IDLE" then return end local hitModel = hit.Parent if hitModel and hitModel ~= char then local hum = hitModel:FindFirstChildOfClass("Humanoid") if hum and hum.Health > 0 then equipTool(RUN_TOOL) autoClickScreen() transitionToRunStart(hitModel) end end end) end if root then bubblePart.Position = root.Position end end if not aiEnabled or not char or not humanoid or not root then return end -- Notice Trigger Detection if not hasTriggeredNotice and currentState == "IDLE" then for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer then local pChar = player.Character local pRoot = pChar and (pChar:FindFirstChild("HumanoidRootPart") or pChar:FindFirstChild("Torso")) if pRoot and (root.Position - pRoot.Position).Magnitude <= 9 then hasTriggeredNotice = true if tPoseTrack then tPoseTrack:Stop() end IdleSound:Stop() NoticeSound:Play() -- Reset Idle Animation by unequipping and equipping unequipAllToolsFast() task.wait(0.1) equipTool(IDLE_TOOL) -- Play sound again after reset IdleSound:Play() break end end end end if currentState == "IDLE" then if not isToolEquipped(IDLE_TOOL) then unequipAllToolsFast(); equipTool(IDLE_TOOL) end if os.clock() - lastKillEndTime < KILL_COOLDOWN then return end if os.clock() - lastScanTime >= 0.2 then lastScanTime = os.clock() local specificTarget = Workspace:FindFirstChild("SCP 096SL") if specificTarget then local tRoot = specificTarget:FindFirstChild("HumanoidRootPart") local tHum = specificTarget:FindFirstChildOfClass("Humanoid") if tRoot and tHum and tHum.Health > 0 and (root.Position - tRoot.Position).Magnitude <= BUBBLE_RADIUS then transitionToRunStart(specificTarget) return end end for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer then local pChar = player.Character local pRoot = pChar and (pChar:FindFirstChild("HumanoidRootPart") or pChar:FindFirstChild("Torso")) local pHum = pChar and pChar:FindFirstChildOfClass("Humanoid") if pRoot and pHum and pHum.Health > 0 and (root.Position - pRoot.Position).Magnitude <= BUBBLE_RADIUS then transitionToRunStart(pChar) return end end end end elseif currentState == "RUN_START" then if not isToolEquipped(RUN_TOOL) then unequipAllToolsFast(); equipTool(RUN_TOOL) end if os.clock() - stateStartTime >= RUN_START_DELAY then transitionToChase() end elseif currentState == "CHASE" then if not currentTarget or not currentTarget.Parent then transitionToIdle(); return end local targetHum = currentTarget:FindFirstChildOfClass("Humanoid") local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart") or currentTarget:FindFirstChild("Torso") if targetHum and targetHum.Health <= 0 then transitionToIdle() return end if not targetHum or not targetRoot then transitionToIdle(); return end if not isToolEquipped(RUN_TOOL) then unequipAllToolsFast(); equipTool(RUN_TOOL) end local distToTarget = (root.Position - targetRoot.Position).Magnitude if distToTarget > SUPER_FAR_DISTANCE then -- Target is too far, freeze movement but maintain state and run animation humanoid:MoveTo(root.Position) else if os.clock() - lastPathTime >= 0.2 then lastPathTime = os.clock() local targetPos = targetRoot.Position if not lastTargetPos or (lastTargetPos - targetPos).Magnitude > 3.0 then lastTargetPos = targetPos -- Smart Pathfinding Config local path = PathfindingService:CreatePath({ AgentRadius = 2.0, AgentHeight = 5.0, WaypointSpacing = 4.0, AgentCanJump = true }) path:ComputeAsync(root.Position, targetPos) if path.Status == Enum.PathStatus.Success then currentWaypoints = path:GetWaypoints() currentWaypointIndex = 2 else -- Path blocked (doors closed, tall places), clear waypoints currentWaypoints = nil end end end if currentWaypoints and currentWaypointIndex <= #currentWaypoints then local targetWp = currentWaypoints[currentWaypointIndex].Position humanoid:MoveTo(targetWp) if (root.Position - Vector3.new(targetWp.X, root.Position.Y, targetWp.Z)).Magnitude < 3.5 then currentWaypointIndex = currentWaypointIndex + 1 end else -- Freeze if target is unreachable (behind door/tall place), but maintain run tool humanoid:MoveTo(root.Position) end end if distToTarget <= KILL_DISTANCE and (os.clock() - chaseStartTime) >= MIN_CHASE_DURATION then transitionToKill(targetHum) end elseif currentState == "KILL" then if currentTarget then local targetRoot = currentTarget:FindFirstChild("HumanoidRootPart") or currentTarget:FindFirstChild("Torso") if targetRoot then humanoid:MoveTo(targetRoot.Position) end end end end)