-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] --[[ BloxStrike ESP - 2D box overlay for BloxStrike (place 114234929420007). The game runs a custom character system: no Humanoid, no model health. Live bodies are Models named after the owning player, holding HumanoidRootPart (Part) + Head (MeshPart), and the authoritative state lives on the Player: Player:GetAttribute("Team") -> "Counter-Terrorists" | "Terrorists" Player:GetAttribute("Health") -> number Player:GetAttribute("MaxHealth") -> number Player:GetAttribute("Dead") -> boolean Player:GetAttribute("Armor") -> JSON { Health, Type } Visibility: the server bakes a PVS (potentially visible set). A character is only streamed to you while it sits inside that set; the moment it leaves, the game re-parents the rig to ReplicatedStorage._PVS_CulledCharacters and stops updating it, so the rig freezes wherever the player was last seen (often their spawn). The rig carries ClientCharacterPresentationVisible on the live state, so a body is only painted while that flag is not false. Because the server withholds off-screen positions there is no true through-wall ESP to be had; instead the last position we actually saw each player at is kept for a few seconds and drawn as a fading "last seen" ghost box. Sound radar: poses are PVS-filtered, but positional noise (footsteps, landings, jumps, reloads, shots) still arrives on the ReplicateSound packet with a raw world Position. Those positions are plotted as fading blips, giving a through-wall hint for players the box ESP can no longer see. The packet carries no owner, so a blip is credited to the nearest player sitting on it; a blip credited to a teammate is dropped (radar-enemies-only), while an unowned blip is kept since hidden enemies are exactly what make unowned noise. Blips run hot red up close to dim amber far off, and anything outside the viewport becomes an edge arrow with a distance readout. Boxes are built head-to-toe from Head/HumanoidRootPart, never from GetBoundingBox, because the culler strands the dropped weapon parts far from the rig and GetBoundingBox then reports absurd 100+ stud boxes. Silent aim hooks the outgoing ShootWeapon packet. The client builds every bullet as { Origin, Direction } from the camera centre ray and ships it to the server, which does the authoritative hit test; nothing about the local muzzle flash, tracer or recoil reads the packet, so rewriting Direction to the target head hits on the server while the screen stays where you look. Trigger bot raycasts straight out of the camera and, only when the crosshair actually lands on a living enemy, fires the equipped weapon through its own :shoot(). The weapon object comes from the controller's own OnInventoryItemEquipped signal, because InventoryController.getCurrentEquipped() self-destructs and returns nil the moment it sees an exploit in its call stack. Spectator bar lists the players watching you, read from each spectator's IsSpectating / SpectatingUserId attributes, and hides itself while you are dead and spectating. Controls: RightShift toggle the overlay Left Alt toggle the panel drag header move the panel ]] local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Workspace = game:GetService("Workspace") local UserInputService = game:GetService("UserInputService") local HttpService = game:GetService("HttpService") local TweenService = game:GetService("TweenService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local LocalPlayer = Players.LocalPlayer if getgenv().BloxStrikeESP and getgenv().BloxStrikeESP.Destroy then getgenv().BloxStrikeESP.Destroy() end local Config = { Enabled = true, Box = true, Name = true, Health = true, Armor = true, Distance = true, Tracer = false, HeadDot = true, Teammates = false, Ghost = true, GhostTime = 4, SoundRadar = true, SoundRadarTime = 2.5, SoundRadarEnemies = true, SilentAim = false, SilentAimFOV = 150, TriggerBot = false, TriggerFOV = 40, Spectators = true, Monitor = false, ToggleKey = Enum.KeyCode.RightShift, EnemyColor = Color3.fromRGB(240, 68, 68), TeamColor = Color3.fromRGB(74, 168, 240), TextColor = Color3.fromRGB(240, 240, 245), OutlineColor = Color3.fromRGB(12, 12, 14), } local Conn = {} local Drawings = {} local active = true -- Last-seen memory. When the server pulls a player out of your PVS the rig is -- re-parented and frozen, so there is nothing live left to read. We keep the -- last world position we actually saw them at (while they were presented) and -- re-project it for a few seconds, fading out, as a "last seen" ghost box. local Ghosts = {} -- Sound radar. Character poses are PVS-filtered, but the server still ships -- positional noise (footsteps, landings, jumps, reloads, gunshots) through the -- ReplicateSound packet with a raw world Position, and that is not filtered the -- same way. Recording those positions gives a through-wall "someone is here" -- blip for players the box ESP can no longer see. local SoundPings = {} local SoundPool = {} local ArrowPool = {} local RadarStats = { dots = 0, arrows = 0 } local function track(connection) table.insert(Conn, connection) return connection end local function worldToScreen(world) local screen, onScreen = Workspace.CurrentCamera:WorldToViewportPoint(world) if screen.Z <= 0 then return nil end return Vector2.new(screen.X, screen.Y), onScreen end -- Unit screen-space direction from the viewport centre to a world point. Used -- for off-screen pings: flip the vector when the point is behind the camera so -- the edge arrow still points the right way. local function screenDirection(position) local camera = Workspace.CurrentCamera if not camera then return 0, -1 end local viewport = camera.ViewportSize local screen = camera:WorldToViewportPoint(position) local dx = screen.X - viewport.X * 0.5 local dy = screen.Y - viewport.Y * 0.5 if screen.Z <= 0 then dx, dy = -dx, -dy end local length = math.sqrt(dx * dx + dy * dy) if length < 0.001 then return 0, -1 end return dx / length, dy / length end -- Blip colour graded by range: hot red up close, dim amber far away, so the -- radar reads distance without a number on every ping. Returns the 0-1 grade -- too, for sizing. local function pingColor(distance) local t = math.clamp((distance - 6) / 74, 0, 1) return t, Color3.fromRGB(255, math.floor(70 + 150 * t), math.floor(64 + 80 * t)) end -- Head-to-toe world points for a rig. Built from Head / feet rather than -- GetBoundingBox, because the PVS culler strands the dropped weapon parts far -- from the rig and GetBoundingBox then reports absurd 100+ stud boxes. local function bodyWorldPoints(body) local head = body:FindFirstChild("Head") local root = body:FindFirstChild("HumanoidRootPart") if not head or not root then return nil end local topWorld = head.Position + Vector3.new(0, head.Size.Y * 0.5, 0) local feetY = root.Position.Y - 2.8 local left = body:FindFirstChild("LeftFoot") local right = body:FindFirstChild("RightFoot") if left and right then feetY = math.min(left.Position.Y - left.Size.Y * 0.5, right.Position.Y - right.Size.Y * 0.5) elseif left then feetY = left.Position.Y - left.Size.Y * 0.5 elseif right then feetY = right.Position.Y - right.Size.Y * 0.5 end local bottomWorld = Vector3.new(root.Position.X, feetY, root.Position.Z) return topWorld, bottomWorld end -- Project a top/bottom world pair to a screen box. Shared by live rigs and the -- "last seen" ghost so both frame the player identically. local function projectBox(topWorld, bottomWorld) local top = worldToScreen(topWorld) local bottom = worldToScreen(bottomWorld) if not top or not bottom then return nil end local height = bottom.Y - top.Y if height < 1 then return nil end local width = height * 0.5 local centerX = (top.X + bottom.X) * 0.5 return Vector2.new(centerX - width * 0.5, top.Y), Vector2.new(width, height) end local function decodeArmor(player) local raw = player:GetAttribute("Armor") if type(raw) ~= "string" or raw == "" then return nil end local ok, data = pcall(function() return HttpService:JSONDecode(raw) end) if ok and type(data) == "table" then local value = tonumber(data.Health) if value and value > 0 then return value end end return nil end local function findBody(player) local body = player.Character if body and body.Parent then return body end local folder = Workspace:FindFirstChild("Characters") if folder then local model = folder:FindFirstChild(player.Name) if model then return model end end local direct = Workspace:FindFirstChild(player.Name) if direct and direct:IsA("Model") then return direct end -- The PVS culler moves occluded characters out of Workspace into this -- folder. We still look there so a rig caught mid-transition (folder moved, -- presentation flag not yet cleared) is not dropped for a frame; the frozen -- rigs that live here permanently are filtered out by isPresented. local culled = ReplicatedStorage:FindFirstChild("_PVS_CulledCharacters") if culled then local model = culled:FindFirstChild(player.Name) if model and model:IsA("Model") then return model end end return nil end local function bodyReady(body) return body and body:FindFirstChild("Head") and body:FindFirstChild("HumanoidRootPart") end -- The server only streams a character while it sits inside your potentially -- visible set. The moment it leaves view the game re-parents the rig to the -- culled folder and stops updating it, so the rig freezes wherever the player -- was last seen (often their spawn). Reading that rig gives a box that never -- tracks, which is the "box stuck at spawn" symptom. The presentation -- controller flags the live state on the rig itself, so only paint a body while -- that flag is not off. local function isPresented(body) return body ~= nil and body:GetAttribute("ClientCharacterPresentationVisible") ~= false end local function acquire(key) local set = Drawings[key] if set then return set end set = { box = Drawing.new("Square"), name = Drawing.new("Text"), distance = Drawing.new("Text"), armorBg = Drawing.new("Square"), armorFill = Drawing.new("Square"), healthBg = Drawing.new("Square"), healthFill = Drawing.new("Square"), tracer = Drawing.new("Line"), head = Drawing.new("Circle"), } set.box.Filled = false set.box.Thickness = 1 set.name.Center = true set.name.Outline = true set.name.Size = 14 set.name.Font = Drawing.Fonts.Plex set.distance.Center = true set.distance.Outline = true set.distance.Size = 13 set.distance.Font = Drawing.Fonts.Plex set.armorBg.Filled = true set.armorFill.Filled = true set.healthBg.Filled = true set.healthFill.Filled = true set.tracer.Thickness = 1 set.head.Thickness = 1 set.head.Filled = true set.head.NumSides = 24 set.head.Radius = 3 Drawings[key] = set return set end local function hide(set) set.box.Visible = false set.name.Visible = false set.distance.Visible = false set.armorBg.Visible = false set.armorFill.Visible = false set.healthBg.Visible = false set.healthFill.Visible = false set.tracer.Visible = false set.head.Visible = false end local function releaseSet(set) for _, drawing in pairs(set) do pcall(function() drawing:Remove() end) end end local function teamOf(player) return player:GetAttribute("Team") end -- Aim targets are rebuilt every frame from the same body lookups the boxes -- use, so silent aim and the trigger bot always see the exact rig the ESP draws. local AimTargets = {} local function rebuildAimTargets() local camera = Workspace.CurrentCamera local list = {} if camera then local localTeam = teamOf(LocalPlayer) for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer then local team = teamOf(player) local enemy = team == nil or team ~= localTeam local dead = player:GetAttribute("Dead") local health = tonumber(player:GetAttribute("Health")) or 0 local spectating = player:GetAttribute("IsSpectating") if enemy and team and not dead and not spectating and health > 0 then local body = findBody(player) if bodyReady(body) and isPresented(body) then local head = body:FindFirstChild("Head") local root = body:FindFirstChild("HumanoidRootPart") local point = worldToScreen(head.Position) list[#list + 1] = { player = player, body = body, head = head, root = root, screen = point, } end end end end end AimTargets = list end -- Closest enemy head to the crosshair inside `fov` pixels, or nil. local function pickTarget(fov) local camera = Workspace.CurrentCamera if not camera then return nil end local center = camera.ViewportSize * 0.5 local best, bestDistance for _, target in ipairs(AimTargets) do if target.screen then local distance = (target.screen - center).Magnitude if distance <= fov and (not bestDistance or distance < bestDistance) then best, bestDistance = target, distance end end end return best end -- Sound radar plumbing. ReplicateSound is a plain RemoteEvent carrying an -- encoded buffer; the game's shared remotes map decodes it, so we attach our -- own listener to that map and read the decoded { Name, Class, Position }. local soundRadarInstalled = false local function acquirePing(index) local set = SoundPool[index] if set then return set end set = { dot = Drawing.new("Circle"), label = Drawing.new("Text") } set.dot.Filled = false set.dot.Thickness = 1 set.dot.NumSides = 24 set.label.Center = true set.label.Outline = true set.label.Size = 12 set.label.Font = Drawing.Fonts.Plex SoundPool[index] = set return set end local function acquireArrow(index) local set = ArrowPool[index] if set then return set end set = { tri = Drawing.new("Triangle"), label = Drawing.new("Text") } set.tri.Filled = true set.label.Center = true set.label.Outline = true set.label.Size = 12 set.label.Font = Drawing.Fonts.Plex ArrowPool[index] = set return set end -- Best known world position for a player: the live rig if it is presented, else -- the last-seen ghost, else nothing. Used to attribute an ownerless sound blip -- to whoever is close to it. local function pingSourcePosition(player) local body = findBody(player) if body then local root = body:FindFirstChild("HumanoidRootPart") if root and isPresented(body) then return root.Position end end local ghost = Ghosts[player] if ghost then return ghost.top end return nil end local function installSoundRadar() if soundRadarInstalled then return end local ok, remotes = pcall(function() return require(ReplicatedStorage.Database.Security.Remotes) end) if not ok or type(remotes) ~= "table" or type(remotes.Sound) ~= "table" then return end local packet = remotes.Sound.ReplicateSound if type(packet) ~= "table" or typeof(packet.Listen) ~= "function" then return end local installed = pcall(function() packet.Listen(function(payload) if not active or not Config.Enabled or not Config.SoundRadar then return end if type(payload) ~= "table" then return end local position = payload.Position if typeof(position) ~= "Vector3" then return end local me = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") if me and (me.Position - position).Magnitude < 4 then return end if #SoundPings > 120 then table.remove(SoundPings, 1) end SoundPings[#SoundPings + 1] = { position = position, time = os.clock(), name = tostring(payload.Name or "noise"), } end) end) soundRadarInstalled = installed end local function drawSoundPings(now) if not (Config.Enabled and Config.SoundRadar and active) then for _, set in pairs(SoundPool) do set.dot.Visible = false set.label.Visible = false end for _, set in pairs(ArrowPool) do set.tri.Visible = false set.label.Visible = false end if #SoundPings > 0 then SoundPings = {} end RadarStats.dots, RadarStats.arrows = 0, 0 return end local camera = Workspace.CurrentCamera if not camera then return end local viewport = camera.ViewportSize local cx, cy = viewport.X * 0.5, viewport.Y * 0.5 local localTeam = teamOf(LocalPlayer) local localRoot = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") local from = localRoot and localRoot.Position or camera.CFrame.Position local lifetime = Config.SoundRadarTime for index = #SoundPings, 1, -1 do if now - SoundPings[index].time > lifetime then table.remove(SoundPings, index) end end -- Attribution table, rebuilt once per frame. A blip is credited to the -- nearest player whose known position sits on it; if that player is a -- teammate the blip is dropped, and a blip nobody owns is kept because an -- unowned sound is exactly what a hidden enemy makes. local candidates = {} for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer then local source = pingSourcePosition(player) if source then candidates[#candidates + 1] = { player = player, position = source, enemy = teamOf(player) == nil or teamOf(player) ~= localTeam, } end end end local dotIndex, arrowIndex = 0, 0 for index = 1, #SoundPings do local ping = SoundPings[index] local fade = math.clamp(1 - (now - ping.time) / lifetime, 0, 1) local distance = (ping.position - from).Magnitude local grade, color = pingColor(distance) local owner, ownerDistance for _, candidate in ipairs(candidates) do local d = (candidate.position - ping.position).Magnitude if d <= 14 and (not ownerDistance or d < ownerDistance) then owner, ownerDistance = candidate, d end end local show = true local label = ping.name if owner then if (not owner.enemy) and Config.SoundRadarEnemies then show = false else label = owner.player.DisplayName ~= "" and owner.player.DisplayName or owner.player.Name color = Color3.fromRGB(255, math.floor(58 + 90 * grade), math.floor(58 + 60 * grade)) end end if show then local point = worldToScreen(ping.position) local onScreen = point and point.X >= 0 and point.X <= viewport.X and point.Y >= 0 and point.Y <= viewport.Y if onScreen then dotIndex += 1 local set = acquirePing(dotIndex) set.dot.Visible = true set.dot.Color = color set.dot.Position = point set.dot.Radius = 4 + 9 * (1 - grade) + 6 * (1 - fade) set.dot.Thickness = 1 + (1 - grade) set.dot.Transparency = fade set.label.Visible = true set.label.Text = label set.label.Color = color set.label.Transparency = fade set.label.Position = point + Vector2.new(0, -16) else arrowIndex += 1 local dirX, dirY = screenDirection(ping.position) local radius = math.min(cx, cy) * 0.86 local tipX, tipY = cx + dirX * radius, cy + dirY * radius local baseX, baseY = cx + dirX * (radius - 15), cy + dirY * (radius - 15) local px, py = -dirY * 8, dirX * 8 local set = acquireArrow(arrowIndex) set.tri.Visible = true set.tri.Color = color set.tri.Transparency = fade set.tri.PointA = Vector2.new(tipX, tipY) set.tri.PointB = Vector2.new(baseX + px, baseY + py) set.tri.PointC = Vector2.new(baseX - px, baseY - py) set.label.Visible = true set.label.Text = math.floor(distance) .. "m" set.label.Color = color set.label.Transparency = fade set.label.Position = Vector2.new(cx + dirX * (radius - 30), cy + dirY * (radius - 30)) end end end for index = dotIndex + 1, #SoundPool do SoundPool[index].dot.Visible = false SoundPool[index].label.Visible = false end for index = arrowIndex + 1, #ArrowPool do ArrowPool[index].tri.Visible = false ArrowPool[index].label.Visible = false end RadarStats.dots, RadarStats.arrows = dotIndex, arrowIndex end local function render() rebuildAimTargets() local camera = Workspace.CurrentCamera if not camera then return end local localTeam = teamOf(LocalPlayer) local viewport = camera.ViewportSize local origin = Vector2.new(viewport.X * 0.5, viewport.Y) local now = os.clock() local live = {} if Config.Enabled then for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer then local team = teamOf(player) local dead = player:GetAttribute("Dead") local health = tonumber(player:GetAttribute("Health")) or 0 local spectating = player:GetAttribute("IsSpectating") local enemy = team == nil or team ~= localTeam local wanted = enemy or Config.Teammates if wanted and team and not dead and not spectating and health > 0 then local body = findBody(player) if bodyReady(body) and isPresented(body) then local topWorld, bottomWorld = bodyWorldPoints(body) local topLeft, size if topWorld then topLeft, size = projectBox(topWorld, bottomWorld) end if topLeft then Ghosts[player] = { top = topWorld, bottom = bottomWorld, time = now } live[player] = { team = team, enemy = enemy, topLeft = topLeft, size = size, health = health, maxHealth = tonumber(player:GetAttribute("MaxHealth")) or 100, armor = decodeArmor(player), body = body, name = player.DisplayName ~= "" and player.DisplayName or player.Name, } end end end end end end for player, set in pairs(Drawings) do if not live[player] then local drawn = false local ghost = Config.Enabled and Config.Ghost and Ghosts[player] if ghost and (now - ghost.time) <= Config.GhostTime then local team = teamOf(player) local enemy = team == nil or team ~= localTeam local wanted = enemy or Config.Teammates local alive = player:GetAttribute("Dead") ~= true and (tonumber(player:GetAttribute("Health")) or 0) > 0 local box, size if alive and wanted then box, size = projectBox(ghost.top, ghost.bottom) end if box then local fade = math.clamp(1 - (now - ghost.time) / Config.GhostTime, 0, 1) local color = enemy and Config.EnemyColor or Config.TeamColor drawn = true set.box.Visible = Config.Box set.box.Color = color set.box.Transparency = fade * 0.55 set.box.Position = box set.box.Size = size local name = player.DisplayName ~= "" and player.DisplayName or player.Name set.name.Visible = Config.Name set.name.Color = Config.TextColor set.name.Transparency = fade * 0.55 set.name.Text = name set.name.Position = Vector2.new(box.X + size.X * 0.5, box.Y - 16) set.tracer.Visible = Config.Tracer set.tracer.Color = color set.tracer.Transparency = fade * 0.55 set.tracer.From = origin set.tracer.To = Vector2.new(box.X + size.X * 0.5, box.Y + size.Y) local point = worldToScreen(ghost.top) set.head.Visible = Config.HeadDot and point ~= nil if point then set.head.Color = color set.head.Transparency = fade * 0.55 set.head.Position = point end set.armorBg.Visible = false set.armorFill.Visible = false set.healthBg.Visible = false set.healthFill.Visible = false set.distance.Visible = false end end if not drawn then hide(set) end end end for player, info in pairs(live) do local set = acquire(player) local tl, size = info.topLeft, info.size local color = info.enemy and Config.EnemyColor or Config.TeamColor local bottom = tl.Y + size.Y if Config.Box then set.box.Visible = true set.box.Color = color set.box.Transparency = 1 set.box.Position = tl set.box.Size = size else set.box.Visible = false end if Config.Name then set.name.Visible = true set.name.Color = Config.TextColor set.name.Transparency = 1 set.name.Text = info.name set.name.Position = Vector2.new(tl.X + size.X * 0.5, tl.Y - 16) else set.name.Visible = false end local barHeight = size.Y local barTop = tl.Y local barWidth = math.clamp(size.X * 0.06, 2, 4) local healthRatio = math.clamp(info.health / math.max(info.maxHealth, 1), 0, 1) if Config.Health then local hx = tl.X - barWidth - 4 set.healthBg.Visible = true set.healthBg.Color = Config.OutlineColor set.healthBg.Position = Vector2.new(hx, barTop) set.healthBg.Size = Vector2.new(barWidth, barHeight) set.healthFill.Visible = true set.healthFill.Color = Color3.fromRGB(255 - 180 * healthRatio, 60 + 180 * healthRatio, 70) set.healthFill.Position = Vector2.new(hx, barTop + barHeight * (1 - healthRatio)) set.healthFill.Size = Vector2.new(barWidth, barHeight * healthRatio) else set.healthBg.Visible = false set.healthFill.Visible = false end if Config.Armor and info.armor then local ratio = math.clamp(info.armor / math.max(info.maxHealth, 1), 0, 1) local ax = tl.X + size.X + 4 set.armorBg.Visible = true set.armorBg.Color = Config.OutlineColor set.armorBg.Position = Vector2.new(ax, barTop) set.armorBg.Size = Vector2.new(barWidth, barHeight) set.armorFill.Visible = true set.armorFill.Color = Color3.fromRGB(90, 150, 255) set.armorFill.Position = Vector2.new(ax, barTop + barHeight * (1 - ratio)) set.armorFill.Size = Vector2.new(barWidth, barHeight * ratio) else set.armorBg.Visible = false set.armorFill.Visible = false end if Config.Distance then local root = info.body:FindFirstChild("HumanoidRootPart") local localRoot = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") local from = localRoot and localRoot.Position or camera.CFrame.Position local meters = math.floor((root.Position - from).Magnitude + 0.5) set.distance.Visible = true set.distance.Color = Config.TextColor set.distance.Text = meters .. "m" set.distance.Position = Vector2.new(tl.X + size.X * 0.5, bottom + 3) else set.distance.Visible = false end if Config.Tracer then set.tracer.Visible = true set.tracer.Color = color set.tracer.Transparency = 1 set.tracer.From = origin set.tracer.To = Vector2.new(tl.X + size.X * 0.5, bottom) else set.tracer.Visible = false end if Config.HeadDot then local head = info.body:FindFirstChild("Head") local point = head and worldToScreen(head.Position) set.head.Visible = point ~= nil if point then set.head.Color = color set.head.Transparency = 1 set.head.Position = point end else set.head.Visible = false end end drawSoundPings(now) end -- Panel look. Flat fields separated by small steps in tone instead of a border -- around every element, one accent colour used only on what is currently on, -- sentence-case labels, and switches instead of rows of identical buttons. local THEME = { ground = Color3.fromRGB(15, 16, 20), header = Color3.fromRGB(21, 22, 27), hover = Color3.fromRGB(31, 33, 40), track = Color3.fromRGB(40, 42, 50), knob = Color3.fromRGB(228, 230, 236), ink = Color3.fromRGB(234, 236, 242), muted = Color3.fromRGB(138, 141, 152), accent = Color3.fromRGB(86, 205, 141), } local PANEL_WIDTH = 236 local GROUPS = { { title = "Visuals", rows = { { key = "Box", label = "Box" }, { key = "Name", label = "Name" }, { key = "Health", label = "Health bar" }, { key = "Armor", label = "Armor bar" }, { key = "Distance", label = "Distance" }, { key = "Tracer", label = "Tracer" }, { key = "HeadDot", label = "Head dot" }, { key = "Ghost", label = "Last seen" }, { key = "SoundRadar", label = "Sound radar" }, { key = "SoundRadarEnemies", label = "Radar enemies only" }, { key = "Teammates", label = "Show teammates" }, }, }, { title = "Aim", rows = { { key = "SilentAim", label = "Silent aim" }, { key = "TriggerBot", label = "Trigger bot" }, }, }, { title = "Interface", rows = { { key = "Spectators", label = "Spectator bar" }, { key = "Monitor", label = "Loadout monitor" }, }, }, } local function buildPanel() local parent = (gethui and gethui()) or game:GetService("CoreGui") local gui = Instance.new("ScreenGui") gui.Name = "BloxStrikeEspGui" gui.ResetOnSpawn = false gui.IgnoreGuiInset = true gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling gui.Parent = parent local frame = Instance.new("Frame") frame.Name = "Panel" frame.AnchorPoint = Vector2.new(0, 0.5) frame.Position = UDim2.new(0, 24, 0.5, 0) frame.Size = UDim2.fromOffset(PANEL_WIDTH, 540) frame.BackgroundColor3 = THEME.ground frame.BorderSizePixel = 0 frame.ClipsDescendants = true frame.Active = true frame.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 12) corner.Parent = frame local header = Instance.new("Frame") header.Name = "Header" header.Size = UDim2.new(1, 0, 0, 52) header.BackgroundColor3 = THEME.header header.BorderSizePixel = 0 header.Parent = frame local title = Instance.new("TextLabel") title.Position = UDim2.fromOffset(16, 11) title.Size = UDim2.new(1, -140, 0, 20) title.BackgroundTransparency = 1 title.Text = "BloxStrike" title.TextColor3 = THEME.ink title.Font = Enum.Font.GothamMedium title.TextSize = 16 title.TextXAlignment = Enum.TextXAlignment.Left title.Parent = header local subtitle = Instance.new("TextLabel") subtitle.Position = UDim2.fromOffset(16, 30) subtitle.Size = UDim2.new(1, -140, 0, 16) subtitle.BackgroundTransparency = 1 subtitle.Text = "ESP overlay" subtitle.TextColor3 = THEME.muted subtitle.Font = Enum.Font.Gotham subtitle.TextSize = 11 subtitle.TextXAlignment = Enum.TextXAlignment.Left subtitle.Parent = header local status = Instance.new("TextLabel") status.AnchorPoint = Vector2.new(1, 0.5) status.Position = UDim2.new(1, -32, 0.5, 0) status.Size = UDim2.fromOffset(150, 18) status.BackgroundTransparency = 1 status.Text = "Idle" status.TextColor3 = THEME.muted status.Font = Enum.Font.Gotham status.TextSize = 12 status.TextXAlignment = Enum.TextXAlignment.Right status.Parent = header local dot = Instance.new("Frame") dot.AnchorPoint = Vector2.new(1, 0.5) dot.Position = UDim2.new(1, -16, 0.5, 0) dot.Size = UDim2.fromOffset(8, 8) dot.BackgroundColor3 = THEME.muted dot.BorderSizePixel = 0 dot.Parent = header local dotCorner = Instance.new("UICorner") dotCorner.CornerRadius = UDim.new(1, 0) dotCorner.Parent = dot local switches = {} local cursor = 62 local function addRow(row) local button = Instance.new("TextButton") button.Position = UDim2.fromOffset(10, cursor) button.Size = UDim2.new(1, -20, 0, 30) button.BackgroundColor3 = THEME.hover button.BackgroundTransparency = 1 button.Text = "" button.AutoButtonColor = false button.BorderSizePixel = 0 button.Parent = frame local rowCorner = Instance.new("UICorner") rowCorner.CornerRadius = UDim.new(0, 7) rowCorner.Parent = button local label = Instance.new("TextLabel") label.Position = UDim2.fromOffset(8, 0) label.Size = UDim2.new(1, -74, 1, 0) label.BackgroundTransparency = 1 label.Text = row.label label.TextColor3 = THEME.ink label.Font = Enum.Font.Gotham label.TextSize = 13 label.TextXAlignment = Enum.TextXAlignment.Left label.Parent = button local pill = Instance.new("Frame") pill.AnchorPoint = Vector2.new(1, 0.5) pill.Position = UDim2.new(1, -6, 0.5, 0) pill.Size = UDim2.fromOffset(34, 18) pill.BackgroundColor3 = THEME.track pill.BorderSizePixel = 0 pill.Parent = button local pillCorner = Instance.new("UICorner") pillCorner.CornerRadius = UDim.new(1, 0) pillCorner.Parent = pill local knob = Instance.new("Frame") knob.AnchorPoint = Vector2.new(0, 0.5) knob.Position = UDim2.new(0, 2, 0.5, 0) knob.Size = UDim2.fromOffset(14, 14) knob.BackgroundColor3 = THEME.knob knob.BorderSizePixel = 0 knob.Parent = pill local knobCorner = Instance.new("UICorner") knobCorner.CornerRadius = UDim.new(1, 0) knobCorner.Parent = knob local function paint(on) pill.BackgroundColor3 = on and THEME.accent or THEME.track TweenService:Create(knob, TweenInfo.new(0.14, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Position = UDim2.new(0, on and 18 or 2, 0.5, 0), }):Play() end paint(Config[row.key]) track(button.MouseEnter:Connect(function() button.BackgroundTransparency = 0 end)) track(button.MouseLeave:Connect(function() button.BackgroundTransparency = 1 end)) track(button.MouseButton1Click:Connect(function() Config[row.key] = not Config[row.key] paint(Config[row.key]) end)) switches[row.key] = paint cursor += 32 end for _, group in ipairs(GROUPS) do local heading = Instance.new("TextLabel") heading.Position = UDim2.fromOffset(18, cursor) heading.Size = UDim2.new(1, -36, 0, 18) heading.BackgroundTransparency = 1 heading.Text = group.title heading.TextColor3 = THEME.muted heading.Font = Enum.Font.GothamMedium heading.TextSize = 11 heading.TextXAlignment = Enum.TextXAlignment.Left heading.Parent = frame cursor += 22 for _, row in ipairs(group.rows) do addRow(row) end cursor += 10 end local hint = Instance.new("TextLabel") hint.Position = UDim2.fromOffset(18, cursor + 2) hint.Size = UDim2.new(1, -36, 0, 16) hint.BackgroundTransparency = 1 hint.Text = "RightShift toggle | Left Alt panel" hint.TextColor3 = THEME.muted hint.Font = Enum.Font.Gotham hint.TextSize = 11 hint.TextXAlignment = Enum.TextXAlignment.Left hint.Parent = frame cursor += 26 frame.Size = UDim2.fromOffset(PANEL_WIDTH, cursor + 8) -- Spectator bar: the game stores the watched player's UserId on each -- spectator (Player:GetAttribute("SpectatingUserId")), so "who is watching -- me" is every other player whose IsSpectating is true and whose -- SpectatingUserId matches LocalPlayer.UserId. Hidden while you are dead -- and spectating, since then the watchers are your own perspective. local spectate = { signature = "\0", rows = {} } local bar = Instance.new("Frame") bar.Name = "SpectatorBar" bar.AnchorPoint = Vector2.new(1, 0) bar.Position = UDim2.new(1, -18, 0, 18) bar.Size = UDim2.fromOffset(190, 34) bar.BackgroundColor3 = THEME.ground bar.BorderSizePixel = 0 bar.ClipsDescendants = true bar.Visible = false bar.ZIndex = 5 bar.Parent = gui local barCorner = Instance.new("UICorner") barCorner.CornerRadius = UDim.new(0, 10) barCorner.Parent = bar local barAccent = Instance.new("Frame") barAccent.Size = UDim2.new(0, 3, 1, 0) barAccent.BackgroundColor3 = THEME.accent barAccent.BorderSizePixel = 0 barAccent.Parent = bar local barTitle = Instance.new("TextLabel") barTitle.Position = UDim2.fromOffset(14, 7) barTitle.Size = UDim2.new(1, -24, 0, 20) barTitle.BackgroundTransparency = 1 barTitle.Text = "Spectating you" barTitle.TextColor3 = THEME.ink barTitle.Font = Enum.Font.GothamMedium barTitle.TextSize = 13 barTitle.TextXAlignment = Enum.TextXAlignment.Left barTitle.Parent = bar local barList = Instance.new("Frame") barList.Position = UDim2.fromOffset(14, 30) barList.Size = UDim2.new(1, -24, 1, -34) barList.BackgroundTransparency = 1 barList.Parent = bar local barLayout = Instance.new("UIListLayout") barLayout.Padding = UDim.new(0, 2) barLayout.SortOrder = Enum.SortOrder.LayoutOrder barLayout.Parent = barList local function updateSpectators() local hidden = LocalPlayer:GetAttribute("Dead") == true or LocalPlayer:GetAttribute("IsSpectating") == true local myId = LocalPlayer.UserId local names = {} if Config.Spectators and not hidden then for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer and player:GetAttribute("IsSpectating") == true and player:GetAttribute("SpectatingUserId") == myId then table.insert(names, player.DisplayName) end end table.sort(names) end local signature = table.concat(names, "\n") if signature == spectate.signature then return end spectate.signature = signature for _, row in ipairs(spectate.rows) do row:Destroy() end spectate.rows = {} if #names == 0 then bar.Visible = false return end bar.Visible = true barTitle.Text = "Spectating you (" .. #names .. ")" bar.Size = UDim2.fromOffset(190, 40 + #names * 18) for index, name in ipairs(names) do local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 0, 16) label.BackgroundTransparency = 1 label.Text = name label.TextColor3 = THEME.ink label.Font = Enum.Font.Gotham label.TextSize = 12 label.TextXAlignment = Enum.TextXAlignment.Left label.TextTruncate = Enum.TextTruncate.AtEnd label.LayoutOrder = index label.Parent = barList spectate.rows[index] = label end end local dragging, dragStart, startPosition track(header.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPosition = frame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end)) track(UserInputService.InputChanged:Connect(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - dragStart frame.Position = UDim2.new( startPosition.X.Scale, startPosition.X.Offset + delta.X, startPosition.Y.Scale, startPosition.Y.Offset + delta.Y ) end end)) local function refresh() status.Text = Config.Enabled and "Armed" or "Idle" status.TextColor3 = Config.Enabled and THEME.accent or THEME.muted dot.BackgroundColor3 = Config.Enabled and THEME.accent or THEME.muted for key, paint in pairs(switches) do paint(Config[key]) end end track(UserInputService.InputBegan:Connect(function(input, processed) if processed then return end if input.KeyCode == Config.ToggleKey then Config.Enabled = not Config.Enabled refresh() elseif input.KeyCode == Enum.KeyCode.LeftAlt then frame.Visible = not frame.Visible end end)) refresh() return gui, refresh, updateSpectators end local gui, refresh, updateSpectators = buildPanel() track(RunService.RenderStepped:Connect(function() local ok, err = pcall(render) if not ok then warn("[BloxStrike ESP] " .. tostring(err)) end local ok2, err2 = pcall(updateSpectators) if not ok2 then warn("[BloxStrike ESP] spectators: " .. tostring(err2)) end end)) track(Players.PlayerRemoving:Connect(function(player) Ghosts[player] = nil local set = Drawings[player] if set then releaseSet(set) Drawings[player] = nil end end)) -- Only touch the shot path while the local player is genuinely in the fight: -- never while dead, respawning, or spectating. This keeps silent aim and the -- trigger bot from injecting shots into the loadout / buy / spawn flow. local function localCanAct() return LocalPlayer:GetAttribute("Dead") ~= true and LocalPlayer:GetAttribute("IsSpectating") ~= true and (tonumber(LocalPlayer:GetAttribute("Health")) or 0) > 0 end -- Silent aim: wrap the outgoing ShootWeapon packet builder. It receives the raw -- table ({ Bullets = {{ Direction, Origin }}, Identifier, Seq, ViewTick, ... }) -- before it is encoded, so redirecting each bullet's Direction to the target -- head is invisible locally and authoritative on the server. local originalSend local function installSilentAim() local ok, remotes = pcall(function() return require(ReplicatedStorage.Database.Security.Remotes) end) if not ok or type(remotes) ~= "table" then return false end local packet = remotes.Inventory and remotes.Inventory.ShootWeapon if not packet or typeof(packet.Send) ~= "function" then return false end originalSend = packet.Send packet.Send = function(payload) pcall(function() if not (Config.SilentAim and localCanAct() and type(payload) == "table") then return end local target = pickTarget(Config.SilentAimFOV) local bullets = target and payload.Bullets if type(bullets) ~= "table" then return end local head = target.head.Position for _, bullet in ipairs(bullets) do local origin = bullet.Origin if typeof(origin) == "Vector3" then local direction = head - origin if direction.Magnitude > 1e-4 then bullet.Direction = direction.Unit end end end end) return originalSend(payload) end return true end local silentAimInstalled = installSilentAim() installSoundRadar() -- Trigger bot, ported from the working Paste Hub BloxStrike edition: cast a ray -- straight out of the camera and fire the weapon's own :shoot() only when that -- ray actually lands on a living enemy. Firing on a real crosshair hit (rather -- than any enemy merely near the crosshair) is what keeps every shot valid. -- -- The weapon object cannot be fetched through InventoryController's public -- getCurrentEquipped(): that accessor walks its own caller stack and returns nil -- (while wiping itself) the instant it sees getgenv or hookfunction in an -- environment, which is exactly what an exploit script looks like. So instead of -- asking the controller, we let the game hand the weapon to us: we listen to the -- controller's own OnInventoryItemEquipped signal, which fires with the freshly -- equipped weapon on every equip (including each respawn's loadout). local CachedInventory local CachedWeapon local weaponEquipConnection local lastTrigger = 0 local function getInventoryController() if CachedInventory then return CachedInventory end local ok, required = pcall(function() return require(ReplicatedStorage.Controllers.InventoryController) end) if not ok or type(required) ~= "table" then return nil end CachedInventory = required return required end local function looksLikeWeapon(value) return type(value) == "table" and typeof(value.shoot) == "function" end local function installWeaponCapture() local controller = getInventoryController() if not controller then return end local signal = controller.OnInventoryItemEquipped if type(signal) ~= "table" or typeof(signal.Connect) ~= "function" then return end weaponEquipConnection = signal:Connect(function(slot, weapon) if not looksLikeWeapon(weapon) then weapon = slot end if looksLikeWeapon(weapon) then CachedWeapon = weapon end end) track(weaponEquipConnection) end local function getWeapon() local controller = getInventoryController() if controller then local peek = controller.peekCurrentEquippedForMovement if typeof(peek) == "function" then local ok, weapon = pcall(peek) if ok and looksLikeWeapon(weapon) then CachedWeapon = weapon return weapon end end end return CachedWeapon end installWeaponCapture() local triggerRayParams = RaycastParams.new() triggerRayParams.FilterType = Enum.RaycastFilterType.Exclude triggerRayParams.IgnoreWater = true local function crosshairEnemy() local camera = Workspace.CurrentCamera if not camera then return false end local character = LocalPlayer.Character triggerRayParams.FilterDescendantsInstances = character and { character } or {} local result = Workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector * 1000, triggerRayParams) local hit = result and result.Instance local body = hit and hit:FindFirstAncestorOfClass("Model") if not body then return false end local player = Players:GetPlayerFromCharacter(body) if not player or player == LocalPlayer then return false end if player:GetAttribute("Dead") or body:GetAttribute("Dead") or body:GetAttribute("Invincible") then return false end return teamOf(player) ~= teamOf(LocalPlayer) end track(RunService.Heartbeat:Connect(function() if not Config.TriggerBot or not localCanAct() or not crosshairEnemy() then return end local weapon = getWeapon() if not weapon or typeof(weapon.shoot) ~= "function" then return end local properties = weapon.Properties if type(properties) ~= "table" then return end if weapon.IsEquipped == false or weapon.IsReloading == true or weapon.IsDestroyed == true then return end if tonumber(weapon.Rounds) and tonumber(weapon.Rounds) <= 0 then return end local fireRate = math.max(tonumber(properties.FireRate) or 0.1, 0.05) local now = os.clock() if now - lastTrigger < fireRate then return end lastTrigger = now pcall(function() weapon:shoot() end) end)) -- Loadout monitor, merged in from the standalone monitor.lua. BloxStrike wipes -- the loadout the instant you die (RemoveInventoryItem x3, then -- CleanupGameLoadout) and hands a fresh one back on respawn; that is ordinary -- game behaviour, not a response to anything this script sends. The monitor -- logs that lifecycle so it can be watched live, and stays silent until the -- panel's Monitor switch is turned on. local monitorInstalled = false local function monitorStateName() local ok, gameState = pcall(function() return require(ReplicatedStorage.Database.Components.GameState).GetState() end) return ok and tostring(gameState) or "?" end local function monitorInventoryCount() local ok, inventory = pcall(function() return require(ReplicatedStorage.Controllers.InventoryController).getCurrentInventory() end) if not ok or type(inventory) ~= "table" then return -1 end local count = 0 for _ in pairs(inventory) do count += 1 end return count end local function monitorLog(format, ...) print("[MON] " .. string.format(format, ...)) end local function installMonitor() if monitorInstalled then return end monitorInstalled = true pcall(function() local remotes = ReplicatedStorage:WaitForChild("NetworkRemotes", 5) remotes = remotes and remotes:FindFirstChild("Inventory") if not remotes then return end local function watch(remote, name) if remote then track(remote.OnClientEvent:Connect(function() if Config.Monitor then monitorLog("%s fired (state=%s)", name, monitorStateName()) end end)) end end watch(remotes:FindFirstChild("CreateGameLoadout"), "CreateGameLoadout") watch(remotes:FindFirstChild("LoadoutResponse"), "LoadoutResponse") watch(remotes:FindFirstChild("RemoveInventoryItem"), "RemoveInventoryItem") watch(remotes:FindFirstChild("CleanupGameLoadout"), "CleanupGameLoadout") end) task.spawn(function() local last = "" while true do task.wait(0.25) if Config.Monitor then local state = monitorStateName() local team = LocalPlayer:GetAttribute("Team") local dead = LocalPlayer:GetAttribute("Dead") local hp = LocalPlayer:GetAttribute("Health") local equipped = LocalPlayer:GetAttribute("CurrentEquipped") local count = monitorInventoryCount() local key = table.concat({ tostring(state), tostring(team), tostring(dead), tostring(hp), tostring(count), tostring(equipped) }, "|") if key ~= last then last = key monitorLog("state=%s team=%s dead=%s hp=%s inv=%d eq=%s", tostring(state), tostring(team), tostring(dead), tostring(hp), count, tostring(equipped)) end end end end) end installMonitor() local api = { Config = Config, SilentAimInstalled = silentAimInstalled, SetEnabled = function(value) Config.Enabled = value and true or false if refresh then refresh() end end, IsEnabled = function() return Config.Enabled end, SetSilentAim = function(value) Config.SilentAim = value and true or false if refresh then refresh() end end, SetTriggerBot = function(value) Config.TriggerBot = value and true or false if refresh then refresh() end end, SetSpectators = function(value) Config.Spectators = value and true or false if refresh then refresh() end end, SetGhost = function(value) Config.Ghost = value and true or false if refresh then refresh() end end, SetSoundRadar = function(value) Config.SoundRadar = value and true or false if refresh then refresh() end end, SetMonitor = function(value) Config.Monitor = value and true or false if refresh then refresh() end end, Spectators = function() local out = {} local myId = LocalPlayer.UserId for _, player in ipairs(Players:GetPlayers()) do if player ~= LocalPlayer and player:GetAttribute("IsSpectating") == true and player:GetAttribute("SpectatingUserId") == myId then table.insert(out, player.Name) end end return out end, Target = function() local target = pickTarget(Config.SilentAimFOV) return target and target.player or nil end, SoundPingCount = function() return #SoundPings end, Radar = function() return { pings = #SoundPings, dots = RadarStats.dots, arrows = RadarStats.arrows } end, Snapshot = function() local out = {} for player, set in pairs(Drawings) do if set.box.Visible then out[player.Name] = { x = set.box.Position.X, y = set.box.Position.Y, w = set.box.Size.X, h = set.box.Size.Y, } end end return out end, Destroy = function() for _, connection in ipairs(Conn) do pcall(function() connection:Disconnect() end) end for _, set in pairs(Drawings) do releaseSet(set) end Drawings = {} for _, set in pairs(SoundPool) do pcall(function() set.dot:Remove() set.label:Remove() end) end SoundPool = {} for _, set in pairs(ArrowPool) do pcall(function() set.tri:Remove() set.label:Remove() end) end ArrowPool = {} SoundPings = {} active = false Conn = {} if silentAimInstalled and originalSend then pcall(function() require(ReplicatedStorage.Database.Security.Remotes).Inventory.ShootWeapon.Send = originalSend end) end if gui then gui:Destroy() end end, } getgenv().BloxStrikeESP = api return api