Keyless
Key Required
Murder Drones Heads Up Display
Lua Script•5302 lines (107700 chars)
--!nocheck
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local SoundService = game:GetService("SoundService")
local StarterGui = game:GetService("StarterGui")
print("[Murder Drones HUD] v18.11 booting...")
-- Cobalt provides STATE during live-reload execution. Luau's analyzer
-- does not know about that injected global, so resolve it through _G.
-- A small fallback is included for environments that do not provide STATE.
local STATE = rawget(_G, "STATE")
if not STATE then
local stateConnections = {}
local stateCleanups = {}
STATE = {}
function STATE.connect(signal, callback)
local connection = signal:Connect(callback)
table.insert(stateConnections, connection)
return connection
end
function STATE.onCleanup(callback)
table.insert(stateCleanups, callback)
end
function STATE.cleanup()
for _, connection in ipairs(stateConnections) do
if connection then
connection:Disconnect()
end
end
for _, callback in ipairs(stateCleanups) do
pcall(callback)
end
table.clear(stateConnections)
table.clear(stateCleanups)
end
end
local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
local YELLOW = Color3.fromRGB(255, 221, 70)
local YELLOW_DIM = Color3.fromRGB(166, 145, 42)
local DARKTINT = Color3.fromRGB(10, 14, 17)
local RED = Color3.fromRGB(255, 72, 82)
local RED_DIM = Color3.fromRGB(125, 32, 42)
local STEEL = Color3.fromRGB(150, 165, 175)
local DEATH_BG = Color3.fromRGB(4, 6, 8)
-- Forward declarations for Luau analyzer visibility. These values/functions are
-- used by HUD callbacks that are defined before their implementation blocks.
local SCAN_RANGE = 90
local SCAN_ARC = 150
local SCAN_DURATION = 0.95
local scanActive = false
local scanStartTime = 0
local terminateNormalCamera
local playConnectionTerminated
local clearClones
local setCamsVisible
local buildClone
local syncPose
local FOOT_TRAIL_LIFETIME = 60
local FOOT_TRAIL_MIN_DIST = 1.5
local FOOTPRINT_HEIGHT = 0.035
local FOOTPRINT_MAX = 250
local FOOTPRINT_BACKTRACK = 10
local FOOTPRINT_HISTORY_INTERVAL = 0.2
-- ============================================================
-- LOCAL AUDIO
-- ============================================================
local AUDIO_FOLDER = "murder_drones_audio"
local AUDIO_FILES = {
open = AUDIO_FOLDER .. "/hud_open.wav",
close = AUDIO_FOLDER .. "/hud_close.wav",
boot = AUDIO_FOLDER .. "/hud_boot.wav",
signalLost = AUDIO_FOLDER .. "/signal_lost.wav",
targetLock = AUDIO_FOLDER .. "/target_lock.wav",
tick = AUDIO_FOLDER .. "/ui_tick.wav",
wingFlap = AUDIO_FOLDER .. "/wing_flap.wav",
flightLoop = AUDIO_FOLDER .. "/flight_loop.wav",
}
local function getLocalAudio(path)
if type(getcustomasset) ~= "function" then
warn("[Murder Drones HUD] getcustomasset() unavailable: " .. path)
return nil
end
if type(isfile) == "function" then
local exists = false
local ok = pcall(function()
exists = isfile(path)
end)
if ok and not exists then
warn("[Murder Drones HUD] Missing local audio: " .. path)
return nil
end
end
local ok, asset = pcall(
getcustomasset,
path
)
if ok and type(asset) == "string" and asset ~= "" then
return asset
end
warn("[Murder Drones HUD] Failed to load local audio: " .. path)
return nil
end
local OPEN_SOUND_ID =
getLocalAudio(AUDIO_FILES.open)
local CLOSE_SOUND_ID =
getLocalAudio(AUDIO_FILES.close)
local INIT_SOUND_ID =
getLocalAudio(AUDIO_FILES.boot)
local SIGNAL_LOST_SOUND_ID =
getLocalAudio(AUDIO_FILES.signalLost)
local TARGET_LOCK_SOUND_ID =
getLocalAudio(AUDIO_FILES.targetLock)
local UI_TICK_SOUND_ID =
getLocalAudio(AUDIO_FILES.tick)
local WING_FLAP_SOUND_ID =
getLocalAudio(AUDIO_FILES.wingFlap)
local FLIGHT_LOOP_SOUND_ID =
getLocalAudio(AUDIO_FILES.flightLoop)
local playSound
-- ============================================================
-- CLEAN OLD HUDS
-- ============================================================
for _, name in ipairs({
"DroneScanner",
"MD_DeathHUD",
"MurderDronesHUD"
}) do
local g = PlayerGui:FindFirstChild(name)
if g then
g:Destroy()
end
end
-- ============================================================
-- STATE
-- ============================================================
local S = {}
S.systemEnabled = false
S.expanded = false
S.trackedPlayer = nil
S.playerEntries = {}
S.activeVisual = nil
S.camClones = {
third = nil,
first = nil,
sourceChar = nil,
environmentCenter = nil,
}
S.camsVisible = false
S.footprintRecords = {}
S.footprintHistory = {}
S.lastHistorySample = 0
-- ============================================================
-- SOLVER / SPYWARE STATE
-- ============================================================
S.solverEnabled = false
S.spywareMode = false
S.spywareTargets = {}
S.spywareFeeds = {}
S.solverRayParts = {}
S.solverContacts = {}
S.scanPopupToken = 0
S.scanResultEntries = {}
S.scanResultSerial = 0
S.scanTargetCount = 0
S.wingsEnabled = false
S.flying = false
S.jumpPressCount = 0
S.lastJumpPress = 0
S.wingModel = nil
S.wingMotors = {}
S.flightVelocity = nil
S.flightGyro = nil
S.flightSound = nil
S.lastFlapSound = 0
S.flightInputDown = nil
S.flightInputUp = nil
S.flightControls = { F = 0, B = 0, L = 0, R = 0, Q = 0, E = 0 }
S.tailModel = nil
S.tailParts = {}
S.tailTools = {}
S.tailLoading = false
S.tailConnections = {}
S.tailWeld = nil
S.tailBaseC0 = nil
local setWingsEnabled
local rebuildSpywareFeeds
S.normalCameraTermination = nil
-- ============================================================
-- MAIN GUI
-- ============================================================
local gui = Instance.new("ScreenGui")
gui.Name = "MurderDronesHUD"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.DisplayOrder = 999
gui.Enabled = true
gui.Parent = PlayerGui
STATE.onCleanup(function()
gui:Destroy()
end)
-- ============================================================
-- ROGUE HUD WATCHER
-- ============================================================
local watcherConn = RunService.Heartbeat:Connect(function()
for _, name in ipairs({
"DroneScanner"
}) do
local rogue = PlayerGui:FindFirstChild(name)
if rogue then
rogue:Destroy()
end
end
end)
STATE.onCleanup(function()
watcherConn:Disconnect()
end)
-- ============================================================
-- SCANNER ROOT
-- ============================================================
local scannerRoot = Instance.new("Frame")
scannerRoot.Name = "ScannerRoot"
scannerRoot.Size = UDim2.fromScale(1, 1)
scannerRoot.BackgroundTransparency = 1
scannerRoot.Visible = false
scannerRoot.Parent = gui
-- ============================================================
-- TINT
-- ============================================================
local tint = Instance.new("Frame")
tint.Size = UDim2.fromScale(1, 1)
tint.BackgroundColor3 = DARKTINT
tint.BackgroundTransparency = 0.88
tint.BorderSizePixel = 0
tint.Parent = scannerRoot
-- ============================================================
-- TOP BAR
-- ============================================================
local topBar = Instance.new("Frame")
topBar.Size = UDim2.new(1, -40, 0, 8)
topBar.Position = UDim2.new(0, 20, 0, 12)
topBar.BackgroundColor3 = YELLOW
topBar.BackgroundTransparency = 0.2
topBar.BorderSizePixel = 0
topBar.Parent = scannerRoot
Instance.new(
"UICorner",
topBar
).CornerRadius = UDim.new(1, 0)
-- ============================================================
-- SCANLINE
-- ============================================================
local scanline = Instance.new("Frame")
scanline.Size = UDim2.new(1, 0, 0, 3)
scanline.BackgroundColor3 = YELLOW
scanline.BackgroundTransparency = 0.6
scanline.BorderSizePixel = 0
scanline.Parent = scannerRoot
STATE.connect(RunService.RenderStepped, function()
local t = (tick() % 4) / 4
scanline.Position =
UDim2.new(0, 0, t, 0)
end)
-- ============================================================
-- DRONE OVERLAY / BASE HUD
-- ============================================================
local function hudText(text, position, size, color, z)
local label = Instance.new("TextLabel")
label.BackgroundTransparency = 1
label.Position = position
label.Size = size
label.Font = Enum.Font.Code
label.Text = text
label.TextColor3 = color or YELLOW_DIM
label.TextSize = 11
label.TextXAlignment = Enum.TextXAlignment.Left
label.ZIndex = z or 4
label.Parent = scannerRoot
return label
end
local hudTL = hudText("UZI // UNIT-00A", UDim2.new(0, 24, 0, 22), UDim2.fromOffset(220, 18), YELLOW, 5)
local hudTR = hudText("OPTICAL LINK :: 100%", UDim2.new(1, -244, 0, 22), UDim2.fromOffset(220, 18), YELLOW, 5)
hudTR.TextXAlignment = Enum.TextXAlignment.Right
local hudBL = hudText("CORE TEMP 031C\nTHRUSTER STANDBY\nNETWORK LOCAL", UDim2.new(0, 24, 1, -112), UDim2.fromOffset(260, 88), STEEL, 5)
local hudBR = hudText("", UDim2.new(1, -294, 1, -112), UDim2.fromOffset(270, 88), YELLOW, 5)
hudBR.TextXAlignment = Enum.TextXAlignment.Right
local normalTelemetry = Instance.new("Frame")
normalTelemetry.Name = "TelemetryPanel"
normalTelemetry.Size = UDim2.fromOffset(250, 122)
normalTelemetry.Position = UDim2.new(1, -320, 1, -254)
normalTelemetry.BackgroundColor3 = DARKTINT
normalTelemetry.BackgroundTransparency = 0.35
normalTelemetry.BorderSizePixel = 0
normalTelemetry.ZIndex = 5
normalTelemetry.Parent = scannerRoot
local normalTelemetryStroke = Instance.new("UIStroke")
normalTelemetryStroke.Color = YELLOW_DIM
normalTelemetryStroke.Thickness = 1
normalTelemetryStroke.Parent = normalTelemetry
local telemetryText = hudText("", UDim2.fromOffset(10, 8), UDim2.new(1, -20, 1, -16), STEEL, 6)
telemetryText.Parent = normalTelemetry
local solverTelemetry = Instance.new("Frame")
solverTelemetry.Name = "SolverTelemetry"
solverTelemetry.Size = UDim2.fromOffset(300, 176)
solverTelemetry.Position = UDim2.new(0, 22, 0, 285)
solverTelemetry.BackgroundColor3 = DARKTINT
solverTelemetry.BackgroundTransparency = 0.28
solverTelemetry.BorderSizePixel = 0
solverTelemetry.Visible = false
solverTelemetry.ZIndex = 6
solverTelemetry.Parent = scannerRoot
local solverTelemetryStroke = Instance.new("UIStroke")
solverTelemetryStroke.Color = RED
solverTelemetryStroke.Thickness = 1.25
solverTelemetryStroke.Parent = solverTelemetry
local solverTelemetryText = hudText("", UDim2.fromOffset(10, 8), UDim2.new(1, -20, 1, -16), YELLOW, 7)
solverTelemetryText.Parent = solverTelemetry
local solverSystemPanel = Instance.new("Frame")
solverSystemPanel.Name = "SolverSystemPanel"
solverSystemPanel.Size = UDim2.fromOffset(300, 150)
solverSystemPanel.Position = UDim2.new(1, -320, 0, 214)
solverSystemPanel.BackgroundColor3 = DARKTINT
solverSystemPanel.BackgroundTransparency = 0.28
solverSystemPanel.BorderSizePixel = 0
solverSystemPanel.Visible = false
solverSystemPanel.ZIndex = 6
solverSystemPanel.Parent = scannerRoot
local solverSystemStroke = Instance.new("UIStroke")
solverSystemStroke.Color = YELLOW
solverSystemStroke.Thickness = 1.25
solverSystemStroke.Parent = solverSystemPanel
local solverSystemText = hudText("", UDim2.fromOffset(10, 8), UDim2.new(1, -20, 1, -16), STEEL, 7)
solverSystemText.Parent = solverSystemPanel
local reticle = Instance.new("Frame")
reticle.Name = "DroneReticle"
reticle.Size = UDim2.fromOffset(34, 34)
reticle.AnchorPoint = Vector2.new(0.5, 0.5)
reticle.Position = UDim2.fromScale(0.5, 0.5)
reticle.BackgroundTransparency = 1
reticle.ZIndex = 4
reticle.Parent = scannerRoot
for _, data in ipairs({
{UDim2.new(0, 0, 0, 0), UDim2.fromOffset(10, 1)},
{UDim2.new(1, -10, 0, 0), UDim2.fromOffset(10, 1)},
{UDim2.new(0, 0, 1, -1), UDim2.fromOffset(10, 1)},
{UDim2.new(1, -10, 1, -1), UDim2.fromOffset(10, 1)},
}) do
local line = Instance.new("Frame")
line.Position = data[1]
line.Size = data[2]
line.BackgroundColor3 = YELLOW_DIM
line.BorderSizePixel = 0
line.Parent = reticle
end
local hudTick = 0
STATE.connect(RunService.RenderStepped, function(dt)
hudTick += dt
local pulse = 0.38 + math.sin(hudTick * 2.4) * 0.10
hudTL.TextTransparency = pulse
hudTR.TextTransparency = pulse
local char = LocalPlayer.Character
local humanoid = char and char:FindFirstChildOfClass("Humanoid")
local root = char and char:FindFirstChild("HumanoidRootPart")
local velocity = root and root.AssemblyLinearVelocity.Magnitude or 0
local health = humanoid and math.max(0, humanoid.Health) or 0
local maxHealth = humanoid and math.max(1, humanoid.MaxHealth) or 100
local ping = 0
pcall(function() ping = math.floor(LocalPlayer:GetNetworkPing() * 1000 + 0.5) end)
local players = math.max(0, #Players:GetPlayers() - 1)
local targetDistance = S.trackedPlayer and S.trackedPlayer.Character and S.trackedPlayer.Character:FindFirstChild("HumanoidRootPart") and root and (S.trackedPlayer.Character.HumanoidRootPart.Position - root.Position).Magnitude or nil
hudBL.Text = string.format("CORE TEMP %03dC\nTHRUSTER %-7s\nNETWORK LOCAL\nVITALS %03d / %03d", 31 + math.floor(math.sin(hudTick) * 2), S.flying and "FLIGHT" or "STANDBY", health, maxHealth)
hudBR.Text = S.solverEnabled and string.format("ABSOLUTE SOLVER\nMODE %s\nVELOCITY %03d\nTARGET %s", S.spywareMode and "SPYWARE" or (scanActive and "SCANNING" or "ACTIVE"), velocity, targetDistance and string.format("%.1f ST", targetDistance) or "NONE") or string.format("SIGNAL %03d%%\nPING %03dMS\nDRONES %02d", math.clamp(100 - math.floor(ping / 8), 0, 100), ping, players)
telemetryText.Text = string.format("// TELEMETRY\nALTITUDE %06.1f\nSPEED %06.1f\nHEALTH %03d%%\nPLAYERS %02d\nTRACK %s\nFLIGHT %s", root and root.Position.Y or 0, velocity, math.floor((health / maxHealth) * 100 + 0.5), players, S.trackedPlayer and S.trackedPlayer.Name or "NONE", S.flying and "ONLINE" or "STANDBY")
if S.solverEnabled then
local scanState = scanActive and string.format("SWEEP %03d%%", math.floor(math.clamp((os.clock() - scanStartTime) / SCAN_DURATION, 0, 1) * 100)) or "READY"
solverTelemetryText.Text = string.format("// SOLVER TELEMETRY\nSTATE ACTIVE\nSCAN %s\nRANGE %03d STUDS\nARC %03d DEG\nTARGETS %02d\nWINGS %s\nFLIGHT %s", scanState, SCAN_RANGE, SCAN_ARC, S.scanTargetCount, S.wingsEnabled and "ONLINE" or "STANDBY", S.flying and "ONLINE" or "STANDBY")
solverSystemText.Text = string.format("// SYSTEM OVERRIDE\nCORE ABSOLUTE SOLVER\nEYE LINK ONLINE\nSPYWARE %02d / 06\nLOCK %s\nMOBILITY %s\nSCAN ENGINE ONE-PASS\nRAYCAST %s", #S.spywareTargets, S.trackedPlayer and S.trackedPlayer.Name or "NONE", S.flying and "FLIGHT" or "GROUND", scanActive and "ACTIVE" or "READY")
solverTelemetry.Visible = true
-- Do not display the Solver System Override panel over spectator cameras
-- or the spyware camera grid.
solverSystemPanel.Visible =
not S.camsVisible
and not S.spywareMode
else
solverTelemetry.Visible = false
solverSystemPanel.Visible = false
end
end)
-- ============================================================
-- BANNER
-- ============================================================
local banner = Instance.new("TextLabel")
banner.Size = UDim2.fromOffset(360, 30)
banner.AnchorPoint = Vector2.new(0.5, 0)
banner.Position = UDim2.new(0.5, 0, 0, 60)
banner.BackgroundTransparency = 1
banner.Font = Enum.Font.Code
banner.TextColor3 = YELLOW
banner.TextSize = 22
banner.Text = ""
banner.Parent = scannerRoot
-- ============================================================
-- PLAYER LIST
-- ============================================================
local listPanel = Instance.new("Frame")
listPanel.Name = "PlayerList"
listPanel.Size = UDim2.fromOffset(200, 32)
listPanel.Position = UDim2.new(0, 20, 0, 40)
listPanel.BackgroundColor3 = DARKTINT
listPanel.BackgroundTransparency = 0.3
listPanel.BorderSizePixel = 0
listPanel.ClipsDescendants = true
listPanel.Parent = scannerRoot
local listStroke = Instance.new("UIStroke")
listStroke.Color = YELLOW
listStroke.Thickness = 1.5
listStroke.Parent = listPanel
local header = Instance.new("TextButton")
header.Size = UDim2.new(1, 0, 0, 32)
header.BackgroundTransparency = 1
header.Font = Enum.Font.Code
header.TextColor3 = YELLOW
header.TextSize = 16
header.Text = "\226\150\184 DRONES (0)"
header.Parent = listPanel
-- ============================================================
-- SPYWARE BUTTON
-- ============================================================
local spywareButton = Instance.new("TextButton")
spywareButton.Name = "SpywareMode"
spywareButton.Size = UDim2.fromOffset(112, 24)
spywareButton.Position = UDim2.new(0, 208, 0, 44)
spywareButton.BackgroundColor3 = DARKTINT
spywareButton.BackgroundTransparency = 0.22
spywareButton.BorderSizePixel = 0
spywareButton.Font = Enum.Font.Code
spywareButton.Text = "SPYWARE [P]"
spywareButton.TextColor3 = YELLOW_DIM
spywareButton.TextSize = 12
spywareButton.AutoButtonColor = false
spywareButton.Visible = false
spywareButton.Parent = scannerRoot
local spywareStroke = Instance.new("UIStroke")
spywareStroke.Color = YELLOW_DIM
spywareStroke.Thickness = 1
spywareStroke.Parent = spywareButton
local wingsButton = Instance.new("TextButton")
wingsButton.Name = "WingsMode"
wingsButton.Size = UDim2.fromOffset(112, 24)
wingsButton.Position = UDim2.new(0, 328, 0, 44)
wingsButton.BackgroundColor3 = DARKTINT
wingsButton.BackgroundTransparency = 0.22
wingsButton.BorderSizePixel = 0
wingsButton.Font = Enum.Font.Code
wingsButton.Text = "WINGS [OFF]"
wingsButton.TextColor3 = YELLOW_DIM
wingsButton.TextSize = 12
wingsButton.AutoButtonColor = false
wingsButton.Visible = false
wingsButton.Parent = scannerRoot
local wingsStroke = Instance.new("UIStroke")
wingsStroke.Color = YELLOW_DIM
wingsStroke.Thickness = 1
wingsStroke.Parent = wingsButton
local raycastButton = Instance.new("TextButton")
raycastButton.Name = "SolverScanButton"
raycastButton.Size = UDim2.fromOffset(112, 24)
raycastButton.Position = UDim2.new(0, 448, 0, 44)
raycastButton.BackgroundColor3 = DARKTINT
raycastButton.BackgroundTransparency = 0.22
raycastButton.BorderSizePixel = 0
raycastButton.Font = Enum.Font.Code
raycastButton.Text = "SCAN [R]"
raycastButton.TextColor3 = RED
raycastButton.TextSize = 12
raycastButton.AutoButtonColor = false
raycastButton.Visible = false
raycastButton.Parent = scannerRoot
local raycastStroke = Instance.new("UIStroke")
raycastStroke.Color = RED
raycastStroke.Thickness = 1
raycastStroke.Parent = raycastButton
-- ============================================================
-- SCROLLER
-- ============================================================
local scroller = Instance.new("ScrollingFrame")
scroller.Position = UDim2.new(0, 0, 0, 32)
scroller.Size = UDim2.new(1, 0, 1, -32)
scroller.BackgroundTransparency = 1
scroller.BorderSizePixel = 0
scroller.ScrollBarThickness = 4
scroller.ScrollBarImageColor3 = YELLOW
scroller.AutomaticCanvasSize = Enum.AutomaticSize.Y
scroller.CanvasSize = UDim2.new(0, 0, 0, 0)
scroller.Parent = listPanel
local listLayout = Instance.new("UIListLayout")
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Parent = scroller
local function updateHeaderCount()
local count = 0
for _ in pairs(S.playerEntries) do
count += 1
end
header.Text =
(S.expanded and "\226\150\190 " or "\226\150\184 ")
.. "DRONES ("
.. count
.. ")"
end
local function setExpanded(state)
S.expanded = state
local targetHeight =
S.expanded and 220 or 32
TweenService:Create(
listPanel,
TweenInfo.new(
0.25,
Enum.EasingStyle.Quad
),
{
Size = UDim2.fromOffset(
200,
targetHeight
)
}
):Play()
updateHeaderCount()
end
header.MouseButton1Click:Connect(function()
setExpanded(not S.expanded)
end)
-- ============================================================
-- TARGET VISUAL
-- ============================================================
local function clearActiveVisual()
if not S.activeVisual then
return
end
if S.activeVisual.highlight then
S.activeVisual.highlight:Destroy()
end
if S.activeVisual.billboard then
S.activeVisual.billboard:Destroy()
end
if S.activeVisual.charConn then
S.activeVisual.charConn:Disconnect()
end
S.activeVisual = nil
end
local function attachVisualTo(plr)
clearActiveVisual()
if not plr then
return
end
local function build(char)
clearActiveVisual()
local hrp =
char:WaitForChild(
"HumanoidRootPart",
5
)
local head =
char:WaitForChild(
"Head",
5
)
if not hrp or not head then
return
end
local highlight = Instance.new("Highlight")
highlight.FillTransparency = 1
highlight.OutlineColor = YELLOW
highlight.OutlineTransparency = 0
highlight.DepthMode =
Enum.HighlightDepthMode.Occluded
highlight.Enabled = S.systemEnabled
highlight.Parent = char
local billboard = Instance.new("BillboardGui")
billboard.Name = "TrackerTag"
billboard.Size = UDim2.fromOffset(105, 22)
billboard.StudsOffset =
Vector3.new(0, 2.8, 0)
billboard.Enabled = S.systemEnabled
billboard.Adornee = head
billboard.Parent = char
local label = Instance.new("TextLabel")
label.BackgroundTransparency = 1
label.Size = UDim2.fromScale(1, 1)
label.Font = Enum.Font.Code
label.TextColor3 = YELLOW
label.TextStrokeTransparency = 0.4
label.TextScaled = true
label.Text = plr.Name
label.Parent = billboard
S.activeVisual = {
highlight = highlight,
billboard = billboard,
hrp = hrp,
lastFootPos = hrp.Position,
char = char,
backtrackSeeded = false,
}
end
if plr.Character then
build(plr.Character)
end
local conn
conn = plr.CharacterAdded:Connect(build)
if S.activeVisual then
S.activeVisual.charConn = conn
else
S.activeVisual = {
charConn = conn
}
end
end
-- ============================================================
-- SPYWARE SELECTION
-- ============================================================
local function isSpywareSelected(plr)
for _, target in ipairs(S.spywareTargets) do
if target == plr then
return true
end
end
return false
end
local function refreshPlayerButtonColors()
for p, entry in pairs(S.playerEntries) do
if S.spywareMode then
entry.listButton.TextColor3 =
isSpywareSelected(p)
and RED
or YELLOW
else
entry.listButton.TextColor3 =
(p == S.trackedPlayer)
and RED
or YELLOW
end
end
end
local function selectTarget(plr)
if S.spywareMode then
local found = nil
for i, target in ipairs(S.spywareTargets) do
if target == plr then
found = i
break
end
end
if found then
table.remove(
S.spywareTargets,
found
)
else
if #S.spywareTargets < 6 then
table.insert(
S.spywareTargets,
plr
)
else
playSound(
UI_TICK_SOUND_ID,
0.35,
1.08,
false
)
end
end
rebuildSpywareFeeds()
banner.Text =
"SOLVER :: SPYWARE // "
.. tostring(#S.spywareTargets)
.. " TARGETS"
refreshPlayerButtonColors()
return
end
if S.trackedPlayer == plr then
S.trackedPlayer = nil
clearActiveVisual()
else
S.trackedPlayer = plr
attachVisualTo(plr)
playSound(
TARGET_LOCK_SOUND_ID,
0.7,
1,
false
)
end
refreshPlayerButtonColors()
end
-- ============================================================
-- FOOTPRINTS
-- ============================================================
local function dropFootprint(
position,
direction,
normal
)
local model = Instance.new("Model")
model.Name = "MurderDronesFootprint"
model.Parent = workspace
local flatDirection = Vector3.new(
direction and direction.X or 0,
0,
direction and direction.Z or 0
)
if flatDirection.Magnitude < 0.05 then
flatDirection =
Vector3.new(0, 0, -1)
end
local groundNormal =
(normal and normal.Magnitude > 0.5)
and normal.Unit
or Vector3.new(0, 1, 0)
local lookCf = CFrame.lookAt(
position,
position + flatDirection.Unit,
groundNormal
)
local function makePart(size, offset)
local p = Instance.new("Part")
p.Name = "Print"
p.Size = size
p.Anchored = true
p.CanCollide = false
p.CanTouch = false
p.CanQuery = false
p.CastShadow = false
p.Material = Enum.Material.Neon
p.Color = YELLOW
p.Transparency = 0.15
p.CFrame =
lookCf
* CFrame.new(
offset.X,
FOOTPRINT_HEIGHT,
offset.Z
)
p.Parent = model
return p
end
makePart(
Vector3.new(
0.42,
0.045,
0.52
),
Vector3.new(0, 0, 0.28)
)
makePart(
Vector3.new(
0.58,
0.045,
0.78
),
Vector3.new(0, 0, -0.28)
)
table.insert(
S.footprintRecords,
{
created = os.clock(),
model = model,
}
)
while #S.footprintRecords >
FOOTPRINT_MAX do
local old =
table.remove(
S.footprintRecords,
1
)
if old and old.model then
old.model:Destroy()
end
end
end
local function addHistorySample(
plr,
char,
hrp
)
if not plr or not char or not hrp then
return nil
end
local history =
S.footprintHistory[plr]
if not history then
history = {}
S.footprintHistory[plr] =
history
end
local last =
history[#history]
if last
and (
hrp.Position
- last.position
).Magnitude < FOOT_TRAIL_MIN_DIST
then
return nil
end
local rayParams =
RaycastParams.new()
rayParams.FilterType =
Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances =
{
char
}
rayParams.IgnoreWater = true
local result =
workspace:Raycast(
hrp.Position
+ Vector3.new(0, 4, 0),
Vector3.new(0, -12, 0),
rayParams
)
if not result then
return nil
end
local direction =
last
and (
hrp.Position
- last.position
)
or hrp.CFrame.LookVector
local sample = {
time = os.clock(),
position = hrp.Position,
ground = result.Position,
normal = result.Normal,
direction = direction,
}
table.insert(
history,
sample
)
local cutoff =
os.clock()
- FOOTPRINT_BACKTRACK
for i = #history, 1, -1 do
if history[i].time < cutoff then
table.remove(history, i)
end
end
return sample
end
local function spawnBacktrack(plr)
local history =
S.footprintHistory[plr]
if not history
or #history == 0
then
return
end
local cutoff =
os.clock()
- FOOTPRINT_BACKTRACK
for _, sample in ipairs(history) do
if sample.time >= cutoff then
dropFootprint(
sample.ground,
sample.direction,
sample.normal
)
end
end
end
local function clearFootprints()
for _, record in ipairs(
S.footprintRecords
) do
if record.model then
record.model:Destroy()
end
end
table.clear(
S.footprintRecords
)
end
local function pruneFootprintHistory()
local cutoff =
os.clock()
- FOOTPRINT_BACKTRACK
for plr, history in pairs(
S.footprintHistory
) do
for i = #history, 1, -1 do
if history[i].time < cutoff then
table.remove(history, i)
end
end
if #history == 0
and not plr.Parent
then
S.footprintHistory[plr] =
nil
end
end
end
local function pruneFootprints()
local now = os.clock()
for i = #S.footprintRecords, 1, -1 do
local record =
S.footprintRecords[i]
if not record.model
or not record.model.Parent
or now - record.created
>= FOOT_TRAIL_LIFETIME
then
if record.model then
record.model:Destroy()
end
table.remove(
S.footprintRecords,
i
)
end
end
end
STATE.connect(
RunService.Heartbeat,
function()
pruneFootprints()
pruneFootprintHistory()
end
)
STATE.onCleanup(function()
clearFootprints()
table.clear(
S.footprintHistory
)
end)
-- ============================================================
-- PLAYER LIST ENTRIES
-- ============================================================
local function setupListEntry(plr)
if plr == LocalPlayer
or S.playerEntries[plr]
then
return
end
local entry = {}
S.playerEntries[plr] =
entry
local btn = Instance.new("TextButton")
btn.Size =
UDim2.new(
1,
0,
0,
26
)
btn.BackgroundTransparency = 1
btn.Font = Enum.Font.Code
btn.Text = plr.Name
btn.TextColor3 = YELLOW
btn.TextSize = 14
btn.TextXAlignment =
Enum.TextXAlignment.Left
btn.Parent = scroller
btn.MouseButton1Click:Connect(
function()
selectTarget(plr)
end
)
entry.listButton = btn
updateHeaderCount()
end
local function teardownListEntry(plr)
local entry =
S.playerEntries[plr]
if not entry then
return
end
-- Preserve a viewed target's camera briefly so the user sees a real
-- disconnect/static sequence instead of the feed vanishing instantly.
if S.trackedPlayer == plr and not S.spywareMode then
clearActiveVisual()
terminateNormalCamera(plr.Name)
end
local leavingFeed = S.spywareFeeds[plr]
if leavingFeed and not leavingFeed.terminating then
leavingFeed.terminating = true
local feedRef = leavingFeed
playConnectionTerminated(feedRef.termination, plr.Name, function()
if feedRef.root and feedRef.root.Parent then
feedRef.root:Destroy()
end
if S.spywareFeeds[plr] == feedRef then
S.spywareFeeds[plr] = nil
end
end)
end
if entry.listButton then
entry.listButton:Destroy()
end
if S.trackedPlayer == plr and not S.normalCameraTermination then
S.trackedPlayer = nil
clearActiveVisual()
end
for i = #S.spywareTargets, 1, -1 do
if S.spywareTargets[i] == plr then
table.remove(
S.spywareTargets,
i
)
end
end
if S.spywareFeeds[plr] and not S.spywareFeeds[plr].terminating then
if S.spywareFeeds[plr].root then
S.spywareFeeds[plr].root:Destroy()
end
S.spywareFeeds[plr] = nil
end
S.playerEntries[plr] = nil
updateHeaderCount()
end
for _, plr in ipairs(
Players:GetPlayers()
) do
setupListEntry(plr)
end
STATE.connect(
Players.PlayerAdded,
setupListEntry
)
STATE.connect(
Players.PlayerRemoving,
teardownListEntry
)
-- Remove stale HUD/world visuals from previous executions. This prevents an
-- older copy of the script from leaving the old Drone Core icon, Solver eye,
-- wings, or flight movers behind when this version starts.
for _, oldGui in ipairs(LocalPlayer:WaitForChild("PlayerGui"):GetChildren()) do
if oldGui.Name == "MurderDronesHUD" and oldGui ~= gui then
oldGui:Destroy()
end
end
local startupCharacter = LocalPlayer.Character
if startupCharacter then
for _, staleName in ipairs({
"AbsoluteSolverEye_Client",
"SolverWings_Client",
"SolverFlightVelocity",
"SolverFlightGyro",
}) do
local stale = startupCharacter:FindFirstChild(staleName)
if stale then stale:Destroy() end
end
end
for _, obj in ipairs(workspace:GetChildren()) do
if obj:IsA("BasePart") and (obj.Name == "SolverRay" or obj.Name:match("^SolverRay_")) then
obj:Destroy()
end
end
-- ============================================================
-- SOLVER SYMBOL (3D ONLY)
-- ============================================================
-- World-space Solver glyph: a real client-side 3D model welded to the
-- player's head. It is yellow and sits slightly forward of the eye so
-- hair/accessories cannot cover it. No screen-space image is used here.
local solverEyeModel = nil
local solverEyeParts = {}
local function clearSolverEyeModel()
if solverEyeModel then
solverEyeModel:Destroy()
solverEyeModel = nil
end
table.clear(solverEyeParts)
end
local function makeSolverEyePart(name, size, cframe, shape)
local part = Instance.new("Part")
part.Name = name
part.Size = size
part.CFrame = cframe
part.Anchored = false
part.CanCollide = false
part.CanTouch = false
part.CanQuery = false
part.Massless = true
part.CastShadow = false
part.Material = Enum.Material.Neon
part.Color = YELLOW
part.Shape = shape or Enum.PartType.Block
part.Parent = solverEyeModel
table.insert(solverEyeParts, part)
return part
end
local function buildSolverEyeModel()
if not S.solverEnabled then return end
local char = LocalPlayer.Character
local head = char and char:FindFirstChild("Head")
if not head then return end
clearSolverEyeModel()
solverEyeModel = Instance.new("Model")
solverEyeModel.Name = "AbsoluteSolverEye_Client"
solverEyeModel.Parent = char
-- Canonical Absolute Solver / Main Translate silhouette:
-- a glowing central hexagon with three thick branches ending in arrowheads.
-- The reference has a solid center rather than the old hollow double-hex.
local base = head.CFrame * CFrame.new(0.24, 0.10, -0.74)
local thickness = 0.045
local function segment(name, a, b, width)
local mid = (a + b) * 0.5
local delta = b - a
local length = delta.Magnitude
local part = makeSolverEyePart(name, Vector3.new(length, width or thickness, width or thickness), CFrame.lookAt(mid, b) * CFrame.Angles(0, math.rad(90), 0))
local weld = Instance.new("WeldConstraint")
weld.Part0 = head
weld.Part1 = part
weld.Parent = part
return part
end
-- Filled hexagonal core, constructed from three crossed neon bars.
-- At eye scale this reads as the six-sided central block from the reference.
local core = {
{Vector3.new(-0.105, 0, 0), Vector3.new(0.105, 0, 0)},
{Vector3.new(-0.052, -0.091, 0), Vector3.new(0.052, 0.091, 0)},
{Vector3.new(-0.052, 0.091, 0), Vector3.new(0.052, -0.091, 0)},
}
for i, pair in ipairs(core) do
segment("CoreHex_" .. i, base:PointToWorldSpace(pair[1]), base:PointToWorldSpace(pair[2]), 0.10)
end
-- Thin six-sided border around the filled center.
local r = 0.145
local points = {}
for i = 0, 5 do
local a = math.rad(30 + i * 60)
points[i + 1] = Vector3.new(math.cos(a) * r, math.sin(a) * r, -0.012)
end
for i = 1, 6 do
segment("HexBorder_" .. i, base:PointToWorldSpace(points[i]), base:PointToWorldSpace(points[i % 6 + 1]), 0.028)
end
-- Three evenly spaced translate arms. Each has a shaft, shoulder, and
-- broad triangular arrowhead, matching the reference image.
local armLength = 0.34
local armWidth = 0.052
local directions = {
math.rad(90),
math.rad(210),
math.rad(330),
}
for i, angle in ipairs(directions) do
local dir = Vector2.new(math.cos(angle), math.sin(angle))
local perp = Vector2.new(-dir.Y, dir.X)
local start2 = dir * 0.14
local neck2 = dir * 0.43
local tip2 = dir * 0.62
segment("Arm_" .. i,
base:PointToWorldSpace(Vector3.new(start2.X, start2.Y, 0)),
base:PointToWorldSpace(Vector3.new(neck2.X, neck2.Y, 0)),
armWidth)
local shoulderA = neck2 + perp * 0.085
local shoulderB = neck2 - perp * 0.085
segment("ShoulderA_" .. i,
base:PointToWorldSpace(Vector3.new(shoulderA.X, shoulderA.Y, 0)),
base:PointToWorldSpace(Vector3.new(tip2.X, tip2.Y, 0)),
0.050)
segment("ShoulderB_" .. i,
base:PointToWorldSpace(Vector3.new(shoulderB.X, shoulderB.Y, 0)),
base:PointToWorldSpace(Vector3.new(tip2.X, tip2.Y, 0)),
0.050)
-- A short central ridge makes the arrowheads visibly solid rather than
-- looking like three separate lines.
local arrowBase = tip2 - dir * 0.15
segment("ArrowRidge_" .. i,
base:PointToWorldSpace(Vector3.new(arrowBase.X, arrowBase.Y, 0)),
base:PointToWorldSpace(Vector3.new(tip2.X, tip2.Y, 0)),
0.070)
end
end
local function updateSolverEyeModel()
if S.solverEnabled then
if not solverEyeModel or solverEyeModel.Parent ~= LocalPlayer.Character then
buildSolverEyeModel()
end
else
clearSolverEyeModel()
end
end
STATE.connect(RunService.RenderStepped, updateSolverEyeModel)
STATE.onCleanup(clearSolverEyeModel)
-- ============================================================
-- SOLVER SCAN RESULT POPUP
-- ============================================================
local scanResult = Instance.new("Frame")
scanResult.Name = "SolverScanResults"
scanResult.Size = UDim2.fromOffset(330, 430)
scanResult.AnchorPoint = Vector2.new(1, 0.5)
scanResult.Position = UDim2.new(1, -28, 0.5, 0)
scanResult.BackgroundTransparency = 1
scanResult.BorderSizePixel = 0
scanResult.ZIndex = 40
scanResult.Parent = scannerRoot
local scanResultLayout = Instance.new("UIListLayout")
scanResultLayout.HorizontalAlignment = Enum.HorizontalAlignment.Right
scanResultLayout.VerticalAlignment = Enum.VerticalAlignment.Center
scanResultLayout.SortOrder = Enum.SortOrder.LayoutOrder
scanResultLayout.Padding = UDim.new(0, 6)
scanResultLayout.Parent = scanResult
local function clearScanResultEntries()
S.scanPopupToken += 1
for player, entry in pairs(S.scanResultEntries) do
if entry.frame then entry.frame:Destroy() end
S.scanResultEntries[player] = nil
end
end
local function hideSolverScanResult()
clearScanResultEntries()
end
local function showSolverScanResult(player, distance)
if not player then return end
S.scanResultSerial += 1
local old = S.scanResultEntries[player]
if old and old.frame then old.frame:Destroy() end
local frame = Instance.new("Frame")
frame.Name = "Target_" .. player.UserId
frame.Size = UDim2.fromOffset(330, 76)
frame.BackgroundColor3 = DARKTINT
frame.BackgroundTransparency = 0.12
frame.BorderSizePixel = 0
frame.LayoutOrder = -S.scanResultSerial
frame.ZIndex = 40
frame.Parent = scanResult
local stroke = Instance.new("UIStroke")
stroke.Color = RED
stroke.Thickness = 1.5
stroke.Parent = frame
local header = Instance.new("TextLabel")
header.Size = UDim2.new(1, -20, 0, 18)
header.Position = UDim2.fromOffset(10, 6)
header.BackgroundTransparency = 1
header.Font = Enum.Font.Code
header.Text = "// SOLVER TARGET ACQUIRED"
header.TextColor3 = RED
header.TextSize = 10
header.TextXAlignment = Enum.TextXAlignment.Right
header.ZIndex = 41
header.Parent = frame
local nameLabel = Instance.new("TextLabel")
nameLabel.Size = UDim2.new(1, -20, 0, 26)
nameLabel.Position = UDim2.fromOffset(10, 24)
nameLabel.BackgroundTransparency = 1
nameLabel.Font = Enum.Font.Code
nameLabel.Text = player.Name
nameLabel.TextColor3 = YELLOW
nameLabel.TextSize = 18
nameLabel.TextXAlignment = Enum.TextXAlignment.Right
nameLabel.TextTruncate = Enum.TextTruncate.AtEnd
nameLabel.ZIndex = 41
nameLabel.Parent = frame
local distanceLabel = Instance.new("TextLabel")
distanceLabel.Size = UDim2.new(1, -20, 0, 18)
distanceLabel.Position = UDim2.fromOffset(10, 50)
distanceLabel.BackgroundTransparency = 1
distanceLabel.Font = Enum.Font.Code
distanceLabel.Text = string.format("DISTANCE // %.1f STUDS", distance)
distanceLabel.TextColor3 = STEEL
distanceLabel.TextSize = 11
distanceLabel.TextXAlignment = Enum.TextXAlignment.Right
distanceLabel.ZIndex = 41
distanceLabel.Parent = frame
S.scanResultEntries[player] = {frame = frame, serial = S.scanResultSerial}
local token = S.scanResultSerial
task.delay(5, function()
local current = S.scanResultEntries[player]
if current and current.serial == token and current.frame == frame then
local tween = TweenService:Create(frame, TweenInfo.new(0.25), {BackgroundTransparency = 1})
local t1 = TweenService:Create(nameLabel, TweenInfo.new(0.25), {TextTransparency = 1})
local t2 = TweenService:Create(distanceLabel, TweenInfo.new(0.25), {TextTransparency = 1})
local t3 = TweenService:Create(header, TweenInfo.new(0.25), {TextTransparency = 1})
tween:Play(); t1:Play(); t2:Play(); t3:Play()
tween.Completed:Wait()
if S.scanResultEntries[player] and S.scanResultEntries[player].frame == frame then
S.scanResultEntries[player] = nil
frame:Destroy()
end
end
end)
end
STATE.onCleanup(hideSolverScanResult)
-- ============================================================
-- SOLVER SCANNER
-- ============================================================
local scanReportedPlayers = {}
local function clearSolverContacts()
for char, highlight in pairs(S.solverContacts) do
if highlight then
highlight:Destroy()
end
S.solverContacts[char] = nil
end
end
local function clearSolverRays()
for _, part in ipairs(S.solverRayParts) do
if part then
part:Destroy()
end
end
table.clear(S.solverRayParts)
end
-- A single large forward sweep. It is triggered manually and runs once from
-- the left edge of the scan cone to the right edge, then disappears.
local function beginSolverScan()
if not S.solverEnabled or scanActive then return end
scanActive = true
scanStartTime = os.clock()
table.clear(scanReportedPlayers)
S.scanTargetCount = 0
clearSolverContacts()
clearSolverRays()
local rayPart = Instance.new("Part")
rayPart.Name = "SolverRay_Scan"
rayPart.Anchored = true
rayPart.CanCollide = false
rayPart.CanTouch = false
rayPart.CanQuery = false
rayPart.CastShadow = false
rayPart.Material = Enum.Material.Neon
rayPart.Color = YELLOW
rayPart.Size = Vector3.new(0.09, 0.09, SCAN_RANGE)
rayPart.Transparency = 0.18
rayPart.Parent = workspace
table.insert(S.solverRayParts, rayPart)
end
local function endSolverScan()
scanActive = false
table.clear(scanReportedPlayers)
clearSolverRays()
clearSolverContacts()
end
-- ============================================================
-- SOLVER WINGS / FLIGHT
-- ============================================================
-- The wings use a real articulated Motor6D hierarchy. The old version
-- treated the feathers as large wedges laid across the back; this version
-- keeps every piece in a controlled local coordinate system so the finished
-- wing is with a broad horizontal silhouette and long pointed outer fingers.
local WING_ASSET_ID = 112392473220517
local WING_SCALE = 2.0
local WING_OFFSET_X = 0.0
local WING_OFFSET_Y = 0.65
local WING_OFFSET_Z = -0.85
local WING_DEPLOY_TIME = 0.85
local WING_POP_DISTANCE = 1.05
local TAIL_ASSET_ID = 80416389405287
local TAIL_SCALE = 1.0
local TAIL_WAG_SPEED = 3.2
local TAIL_WAG_AMOUNT = 0.14
local IY_FLY_SPEED = 1
local FLIGHT_SPEED = 50
local wingDeployAlpha = 0
local wingDeployStarted = 0
local function getFlightRig()
local char = LocalPlayer.Character
if not char then return nil, nil, nil end
local humanoid = char:FindFirstChildOfClass("Humanoid")
local root = char:FindFirstChild("HumanoidRootPart")
local torso = char:FindFirstChild("UpperTorso") or char:FindFirstChild("Torso")
return humanoid, root, torso
end
local function stopFlight()
S.flying = false
if S.flightInputDown then S.flightInputDown:Disconnect(); S.flightInputDown = nil end
if S.flightInputUp then S.flightInputUp:Disconnect(); S.flightInputUp = nil end
if S.flightVelocity then S.flightVelocity:Destroy(); S.flightVelocity = nil end
if S.flightGyro then S.flightGyro:Destroy(); S.flightGyro = nil end
if S.flightSound then S.flightSound:Destroy(); S.flightSound = nil end
S.flightControls = {F = 0, B = 0, L = 0, R = 0, Q = 0, E = 0}
local humanoid = select(1, getFlightRig())
if humanoid then humanoid.PlatformStand = false; humanoid.AutoRotate = true end
pcall(function() workspace.CurrentCamera.CameraType = Enum.CameraType.Custom end)
end
-- ============================================================
-- CATALOG-MODEL WINGS
-- ============================================================
-- Instead of approximating the reference with Parts/WedgeParts, this build
-- asks Roblox for the actual UGC accessory model by catalog asset ID. The
-- accessory is cloned locally and attached to the live character, so the
-- visible wing geometry/material/tears come from the catalog model itself.
local function findAccessoryModel(container)
for _, child in ipairs(container:GetDescendants()) do
if child:IsA("Accessory") then
return child
end
end
return nil
end
local function loadCatalogWingAccessory()
local description = Instance.new("HumanoidDescription")
description.ShouldersAccessory = tostring(WING_ASSET_ID)
local ok, dummyOrError = pcall(function()
return Players:CreateHumanoidModelFromDescriptionAsync(
description,
Enum.HumanoidRigType.R15
)
end)
description:Destroy()
if not ok or not dummyOrError then
warn("[Murder Drones HUD] Failed to load catalog wing asset:", dummyOrError)
return nil
end
local dummy = dummyOrError
local sourceAccessory = findAccessoryModel(dummy)
if not sourceAccessory then
-- A few catalog items are classified as back accessories even when the
-- thumbnail/description presents them as shoulder-mounted wings.
local fallbackDescription = Instance.new("HumanoidDescription")
fallbackDescription.BackAccessory = tostring(WING_ASSET_ID)
local fallbackOk, fallbackDummy = pcall(function()
return Players:CreateHumanoidModelFromDescriptionAsync(
fallbackDescription,
Enum.HumanoidRigType.R15
)
end)
fallbackDescription:Destroy()
dummy:Destroy()
if not fallbackOk or not fallbackDummy then
warn("[Murder Drones HUD] Catalog wing could not be resolved as a shoulder or back accessory:", fallbackDummy)
return nil
end
dummy = fallbackDummy
sourceAccessory = findAccessoryModel(dummy)
end
if not sourceAccessory then
dummy:Destroy()
warn("[Murder Drones HUD] Catalog wing asset returned no Accessory instance.")
return nil
end
local clone = sourceAccessory:Clone()
dummy:Destroy()
return clone
end
local function scaleCatalogAccessory(accessory, scale)
local handle = accessory and accessory:FindFirstChild("Handle")
if not handle or not handle:IsA("BasePart") then return end
-- Scale the actual mesh assembly around the Handle. Attachment.CFrame is
-- local to its parent, so capture each local attachment transform BEFORE
-- moving/scaling the parent parts, then scale only its local position.
local pivot = handle.CFrame
local attachmentFrames = {}
for _, descendant in ipairs(accessory:GetDescendants()) do
if descendant:IsA("Attachment") then
attachmentFrames[descendant] = descendant.CFrame
end
end
for _, descendant in ipairs(accessory:GetDescendants()) do
if descendant:IsA("BasePart") then
local relative = pivot:ToObjectSpace(descendant.CFrame)
descendant.Size *= scale
descendant.CFrame = pivot * CFrame.fromMatrix(
relative.Position * scale,
relative.XVector,
relative.YVector,
relative.ZVector
)
local specialMesh = descendant:FindFirstChildOfClass("SpecialMesh")
if specialMesh then
specialMesh.Scale *= scale
end
end
end
for attachment, localCF in pairs(attachmentFrames) do
if attachment and attachment.Parent then
attachment.CFrame = CFrame.new(localCF.Position * scale) * localCF.Rotation
end
end
end
local function attachCatalogAccessory(accessory, character)
if not accessory or not character then return nil end
local torso = character:FindFirstChild("UpperTorso") or character:FindFirstChild("Torso")
if not torso then return nil end
local handle = accessory:FindFirstChild("Handle")
if not handle or not handle:IsA("BasePart") then
return nil
end
local handleAttachment
for _, child in ipairs(handle:GetChildren()) do
if child:IsA("Attachment") then
handleAttachment = child
break
end
end
local bodyAttachment
if handleAttachment then
bodyAttachment = torso:FindFirstChild(handleAttachment.Name)
end
accessory.Parent = character
handle.CanCollide = false
handle.CanTouch = false
handle.CanQuery = false
handle.Massless = true
-- Rebuild the accessory weld against the live torso. This preserves the
-- exact mesh while letting the HUD animate the whole catalog accessory.
for _, child in ipairs(handle:GetChildren()) do
if child:IsA("Weld") or child:IsA("WeldConstraint") or child:IsA("Motor6D") then
child:Destroy()
end
end
local weld = Instance.new("Weld")
weld.Name = "SolverCatalogWingWeld"
weld.Part0 = handle
weld.Part1 = torso
if handleAttachment and bodyAttachment then
-- Keep the catalog attachment orientation, but deliberately move the
-- entire wing assembly up and behind the torso. The previous build
-- snapped the UGC attachment directly onto the torso attachment, which
-- put the wings at the character's lower-back/"ass" position.
weld.C0 = handleAttachment.CFrame
weld.C1 = bodyAttachment.CFrame * CFrame.new(WING_OFFSET_X, WING_OFFSET_Y, WING_OFFSET_Z)
else
weld.C0 = CFrame.identity
weld.C1 = CFrame.new(WING_OFFSET_X, WING_OFFSET_Y, WING_OFFSET_Z)
end
weld.Parent = handle
return {
accessory = accessory,
handle = handle,
weld = weld,
baseC0 = weld.C0,
}
end
local function clearWings()
stopFlight()
for _, assembly in ipairs(S.wingMotors) do
if assembly.accessory and assembly.accessory.Parent then
assembly.accessory:Destroy()
end
end
table.clear(S.wingMotors)
if S.wingModel then S.wingModel:Destroy(); S.wingModel = nil end
S.wingLoading = false
wingDeployAlpha = 0
end
local function buildWings()
if S.wingModel and S.wingModel.Parent then return end
if S.wingLoading then return end
local character = LocalPlayer.Character
if not character then return end
S.wingLoading = true
task.spawn(function()
local accessory = loadCatalogWingAccessory()
if not S.wingsEnabled or LocalPlayer.Character ~= character then
if accessory then accessory:Destroy() end
S.wingLoading = false
return
end
if not accessory then
S.wingLoading = false
return
end
local model = Instance.new("Model")
model.Name = "SolverWings_CatalogMesh"
model.Parent = character
S.wingModel = model
scaleCatalogAccessory(accessory, WING_SCALE)
local record = attachCatalogAccessory(accessory, character)
if not record then
accessory:Destroy()
model:Destroy()
S.wingModel = nil
S.wingLoading = false
return
end
accessory.Parent = model
table.insert(S.wingMotors, record)
wingDeployAlpha = 0
wingDeployStarted = os.clock()
S.wingLoading = false
end)
end
-- ============================================================
-- LEGACY MURDER DRONES TAIL
-- ============================================================
-- The supplied Tail asset is an old client-side character script rather than
-- a normal accessory. We borrow its model/tool-replication approach, but keep
-- the final pose anchored to the character instead of the mouse/cursor.
local function clearTail()
for _, connection in ipairs(S.tailConnections) do
if connection then connection:Disconnect() end
end
table.clear(S.tailConnections)
for _, part in ipairs(S.tailParts) do
if part and part.Parent then part:Destroy() end
end
table.clear(S.tailParts)
local backpack = LocalPlayer:FindFirstChild("Backpack")
for _, tool in ipairs(S.tailTools) do
if tool and tool.Parent then
local fake = tool:FindFirstChild("FakeHandle")
if fake then fake:Destroy() end
local handle = tool:FindFirstChild("Handle")
if handle then
for _, child in ipairs(handle:GetChildren()) do
if child.Name == "SolverTailWeld" or (child:IsA("Weld") and child.Part0 == fake) then child:Destroy() end
end
end
if backpack then tool.Parent = backpack end
end
end
table.clear(S.tailTools)
if S.tailModel and S.tailModel.Parent then
S.tailModel:Destroy()
end
S.tailModel = nil
S.tailWeld = nil
S.tailBaseC0 = nil
S.tailLoading = false
end
local function loadCatalogTailAccessory()
local function findAccessoryModel(container)
for _, child in ipairs(container:GetDescendants()) do
if child:IsA("Accessory") then
return child
end
end
return nil
end
local function tryDescription(propertyName)
local description = Instance.new("HumanoidDescription")
if propertyName == "BackAccessory" then
description.BackAccessory = tostring(TAIL_ASSET_ID)
else
description.WaistAccessory = tostring(TAIL_ASSET_ID)
end
local ok, dummyOrError = pcall(function()
return Players:CreateHumanoidModelFromDescriptionAsync(
description,
Enum.HumanoidRigType.R15
)
end)
description:Destroy()
if not ok or not dummyOrError then
return nil, dummyOrError
end
local dummy = dummyOrError
local accessory = findAccessoryModel(dummy)
if not accessory then
dummy:Destroy()
return nil, "no Accessory returned"
end
local clone = accessory:Clone()
dummy:Destroy()
return clone
end
local accessory, err = tryDescription("BackAccessory")
if not accessory then
accessory, err = tryDescription("WaistAccessory")
end
if not accessory then
warn("[Murder Drones HUD] Solver tail accessory could not be loaded:", err)
return nil
end
return accessory
end
local function scaleTailAccessory(accessory, scale)
if not accessory or scale == 1 then return end
local handle = accessory:FindFirstChild("Handle")
if not handle or not handle:IsA("BasePart") then return end
local pivot = handle.CFrame
local attachmentFrames = {}
for _, descendant in ipairs(accessory:GetDescendants()) do
if descendant:IsA("Attachment") then
attachmentFrames[descendant] = descendant.CFrame
end
end
for _, descendant in ipairs(accessory:GetDescendants()) do
if descendant:IsA("BasePart") then
local relative = pivot:ToObjectSpace(descendant.CFrame)
descendant.Size *= scale
descendant.CFrame = pivot * CFrame.fromMatrix(
relative.Position * scale,
relative.XVector,
relative.YVector,
relative.ZVector
)
local mesh = descendant:FindFirstChildOfClass("SpecialMesh")
if mesh then mesh.Scale *= scale end
end
end
for attachment, localCF in pairs(attachmentFrames) do
if attachment and attachment.Parent then
attachment.CFrame = CFrame.new(localCF.Position * scale) * localCF.Rotation
end
end
end
local function attachCatalogTail(accessory, character)
if not accessory or not character then return nil end
local torso = character:FindFirstChild("UpperTorso")
or character:FindFirstChild("LowerTorso")
or character:FindFirstChild("Torso")
or character:FindFirstChild("HumanoidRootPart")
if not torso or not torso:IsA("BasePart") then return nil end
local handle = accessory:FindFirstChild("Handle")
if not handle or not handle:IsA("BasePart") then return nil end
local handleAttachment
for _, child in ipairs(handle:GetChildren()) do
if child:IsA("Attachment") then
handleAttachment = child
break
end
end
local bodyAttachment
if handleAttachment then
bodyAttachment = torso:FindFirstChild(handleAttachment.Name)
end
if not bodyAttachment then
for _, name in ipairs({"BodyBackAttachment", "WaistBackAttachment", "BackAttachment"}) do
local candidate = torso:FindFirstChild(name)
if candidate and candidate:IsA("Attachment") then
bodyAttachment = candidate
break
end
end
end
accessory.Parent = character
handle.CanCollide = false
handle.CanTouch = false
handle.CanQuery = false
handle.Massless = true
for _, child in ipairs(handle:GetChildren()) do
if child:IsA("Weld") or child:IsA("WeldConstraint") or child:IsA("Motor6D") then
child:Destroy()
end
end
local weld = Instance.new("Weld")
weld.Name = "SolverTailWeld"
weld.Part0 = handle
weld.Part1 = torso
if handleAttachment and bodyAttachment then
weld.C0 = handleAttachment.CFrame
weld.C1 = bodyAttachment.CFrame
else
weld.C0 = CFrame.new(0, -0.1, 0.45)
weld.C1 = CFrame.identity
end
weld.Parent = handle
return {
accessory = accessory,
handle = handle,
weld = weld,
baseC0 = weld.C0,
}
end
local function buildTail()
if S.tailModel and S.tailModel.Parent then return end
if S.tailLoading then return end
local character = LocalPlayer.Character
if not character then return end
S.tailLoading = true
task.spawn(function()
local accessory = loadCatalogTailAccessory()
if not accessory then
S.tailLoading = false
return
end
if not S.wingsEnabled or LocalPlayer.Character ~= character then
accessory:Destroy()
S.tailLoading = false
return
end
local model = Instance.new("Model")
model.Name = "SolverTail_CatalogMesh"
model.Parent = character
S.tailModel = model
scaleTailAccessory(accessory, TAIL_SCALE)
local record = attachCatalogTail(accessory, character)
if not record then
accessory:Destroy()
model:Destroy()
S.tailModel = nil
S.tailLoading = false
warn("[Murder Drones HUD] Solver tail accessory had no usable Handle/attachment.")
return
end
accessory.Parent = model
S.tailWeld = record.weld
S.tailBaseC0 = record.baseC0
S.tailLoading = false
end)
end
local function startFlight()
if S.flying or not S.wingsEnabled or not S.solverEnabled then return end
local humanoid, root = getFlightRig(); if not humanoid or not root then return end
buildWings(); S.flying=true; humanoid.PlatformStand=true; humanoid.AutoRotate=false
S.flightControls={F=0,B=0,L=0,R=0,Q=0,E=0}
S.flightVelocity=Instance.new("BodyVelocity"); S.flightVelocity.Name="SolverFlightVelocity"; S.flightVelocity.MaxForce=Vector3.new(9e9,9e9,9e9); S.flightVelocity.Velocity=Vector3.zero; S.flightVelocity.Parent=root
S.flightGyro=Instance.new("BodyGyro"); S.flightGyro.Name="SolverFlightGyro"; S.flightGyro.P=9e4; S.flightGyro.MaxTorque=Vector3.new(9e9,9e9,9e9); S.flightGyro.CFrame=root.CFrame; S.flightGyro.Parent=root
S.flightInputDown=UserInputService.InputBegan:Connect(function(input,processed)
if processed then return end
if input.KeyCode==Enum.KeyCode.W then S.flightControls.F=IY_FLY_SPEED elseif input.KeyCode==Enum.KeyCode.S then S.flightControls.B=-IY_FLY_SPEED elseif input.KeyCode==Enum.KeyCode.A then S.flightControls.L=-IY_FLY_SPEED elseif input.KeyCode==Enum.KeyCode.D then S.flightControls.R=IY_FLY_SPEED elseif input.KeyCode==Enum.KeyCode.E then S.flightControls.Q=IY_FLY_SPEED*2 elseif input.KeyCode==Enum.KeyCode.Q then S.flightControls.E=-IY_FLY_SPEED*2 end
end)
S.flightInputUp=UserInputService.InputEnded:Connect(function(input,processed)
if processed then return end
if input.KeyCode==Enum.KeyCode.W then S.flightControls.F=0 elseif input.KeyCode==Enum.KeyCode.S then S.flightControls.B=0 elseif input.KeyCode==Enum.KeyCode.A then S.flightControls.L=0 elseif input.KeyCode==Enum.KeyCode.D then S.flightControls.R=0 elseif input.KeyCode==Enum.KeyCode.E then S.flightControls.Q=0 elseif input.KeyCode==Enum.KeyCode.Q then S.flightControls.E=0 end
end)
if FLIGHT_LOOP_SOUND_ID then
S.flightSound=Instance.new("Sound"); S.flightSound.Name="SolverFlightLoop"; S.flightSound.SoundId=FLIGHT_LOOP_SOUND_ID; S.flightSound.Looped=true; S.flightSound.Volume=.25; S.flightSound.Parent=root; S.flightSound:Play()
end
end
setWingsEnabled = function(state)
S.wingsEnabled = state and S.solverEnabled
wingsButton.Text = S.wingsEnabled and "WINGS [ON]" or "WINGS [OFF]"
wingsButton.TextColor3 = S.wingsEnabled and RED or YELLOW_DIM
wingsStroke.Color = S.wingsEnabled and RED or YELLOW_DIM
if S.wingsEnabled then buildWings(); buildTail() else clearWings(); clearTail() end
end
wingsButton.MouseButton1Click:Connect(function()
if S.solverEnabled then setWingsEnabled(not S.wingsEnabled) end
end)
raycastButton.Text = "SCAN [R]"
raycastButton.TextColor3 = YELLOW_DIM
raycastStroke.Color = YELLOW_DIM
raycastButton.MouseButton1Click:Connect(function()
beginSolverScan()
end)
STATE.connect(UserInputService.InputBegan, function(input, processed)
if processed or not S.solverEnabled then return end
if input.KeyCode == Enum.KeyCode.R then
beginSolverScan()
end
end)
STATE.connect(RunService.RenderStepped, function(dt)
if not S.wingsEnabled then return end
if not S.wingModel or not S.wingModel.Parent then buildWings() end
local now = os.clock()
local deployT = math.clamp((now - wingDeployStarted) / WING_DEPLOY_TIME, 0, 1)
wingDeployAlpha = 1 - ((1 - deployT) ^ 3)
if S.flying and now - S.lastFlapSound >= 0.24 then
S.lastFlapSound = now
playSound(WING_FLAP_SOUND_ID, 0.32, 1.05, false)
end
for _, wing in ipairs(S.wingMotors) do
if wing.weld and wing.weld.Parent then
local flapAngle = 0
if S.flying then
flapAngle = math.sin(now * 8.2) * 0.16
else
flapAngle = math.sin(now * 1.8) * 0.018
end
local deployAlpha = wingDeployAlpha
local deployAngle = math.rad(18 * (1 - deployAlpha))
local pop = WING_POP_DISTANCE * (1 - deployAlpha)
wing.weld.C0 = wing.baseC0 * CFrame.new(0, 0, -pop) * CFrame.Angles(deployAngle + flapAngle, 0, 0)
end
end
-- The tail never reads the mouse/camera. Its motion is a small autonomous
-- idle wag so it stays attached to the character.
if S.tailModel and S.tailModel.Parent then
local torso = LocalPlayer.Character and (LocalPlayer.Character:FindFirstChild("LowerTorso") or LocalPlayer.Character:FindFirstChild("UpperTorso") or LocalPlayer.Character:FindFirstChild("Torso"))
if torso then
local wag = math.sin(now * TAIL_WAG_SPEED) * TAIL_WAG_AMOUNT
-- Legacy/tool tails are already driven from the body-relative offsets above.
-- Do not cumulatively rotate their parts here; doing so causes drift.
if S.tailWeld and S.tailWeld.Parent then
-- Animate the weld, not a welded part's world CFrame.
S.tailWeld.C0 = (S.tailBaseC0 or S.tailWeld.C0) * CFrame.Angles(0, wag * 0.35, 0)
end
end
end
if not S.flying then return end
local humanoid, root = getFlightRig()
if not humanoid or not root or not S.flightVelocity or not S.flightGyro then
stopFlight()
return
end
local camera = workspace.CurrentCamera
if not camera then return end
local controlX = S.flightControls.L + S.flightControls.R
local controlZ = S.flightControls.F + S.flightControls.B
local controlY = S.flightControls.Q + S.flightControls.E
if controlX ~= 0 or controlZ ~= 0 or controlY ~= 0 then
S.flightVelocity.Velocity = ((camera.CFrame.LookVector * controlZ) + ((camera.CFrame * CFrame.new(controlX, (controlZ + controlY) * 0.2, 0).Position) - camera.CFrame.Position)) * FLIGHT_SPEED
else
S.flightVelocity.Velocity = Vector3.zero
end
S.flightGyro.CFrame = camera.CFrame
end)
local function updateSolver()
if not S.solverEnabled or not scanActive then
if #S.solverRayParts > 0 or next(S.solverContacts) ~= nil then
clearSolverRays()
clearSolverContacts()
end
return
end
local elapsed = os.clock() - scanStartTime
local progress = math.clamp(elapsed / SCAN_DURATION, 0, 1)
if progress >= 1 then
endSolverScan()
return
end
local char = LocalPlayer.Character
local hrp = char and char:FindFirstChild("HumanoidRootPart")
local head = char and char:FindFirstChild("Head")
if not hrp or not head then
endSolverScan()
return
end
-- One pass only: left edge -> center -> right edge. The ray now originates
-- from the player's character, so camera movement cannot move the scanner.
local halfArc = math.rad(SCAN_ARC * 0.5)
local scanAngle = -halfArc + (halfArc * 2 * progress)
local flatLook = Vector3.new(hrp.CFrame.LookVector.X, 0, hrp.CFrame.LookVector.Z)
if flatLook.Magnitude < 0.01 then
flatLook = Vector3.new(0, 0, -1)
end
flatLook = flatLook.Unit
local baseAngle = math.atan2(-flatLook.Z, flatLook.X)
local rayAngle = baseAngle + scanAngle
local direction = Vector3.new(math.cos(rayAngle), 0, -math.sin(rayAngle)).Unit
local origin = hrp.Position + Vector3.new(0, 0.15, 0)
local targetCharacters = {}
for _, player in ipairs(Players:GetPlayers()) do
if player ~= LocalPlayer and player.Character then
table.insert(targetCharacters, player.Character)
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = targetCharacters
params.IgnoreWater = true
local result = #targetCharacters > 0 and workspace:Raycast(origin, direction * SCAN_RANGE, params) or nil
local distance = result and (result.Position - origin).Magnitude or SCAN_RANGE
local rayPart = S.solverRayParts[1]
if rayPart then
rayPart.Size = Vector3.new(0.09, 0.09, distance)
rayPart.CFrame = CFrame.lookAt(origin + direction * distance * 0.5, origin + direction * distance)
rayPart.Color = result and RED or YELLOW
rayPart.Transparency = result and 0.02 or 0.18
end
if result then
local model = result.Instance:FindFirstAncestorOfClass("Model")
local player = model and Players:GetPlayerFromCharacter(model)
if player and player ~= LocalPlayer then
if not S.solverContacts[model] then
local h = Instance.new("Highlight")
h.Name = "SolverContact"
h.FillTransparency = 1
h.OutlineColor = RED
h.OutlineTransparency = 0
h.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
h.Parent = model
S.solverContacts[model] = h
end
if not scanReportedPlayers[player] then
scanReportedPlayers[player] = true
S.scanTargetCount += 1
showSolverScanResult(player, distance)
end
end
end
end
STATE.connect(
RunService.Heartbeat,
function()
if S.solverEnabled
and S.systemEnabled
then
updateSolver()
end
end
)
-- ============================================================
-- CAMERA HOLDER
-- ============================================================
local camHolder =
Instance.new("Frame")
camHolder.Size =
UDim2.fromOffset(
180,
0
)
camHolder.AnchorPoint =
Vector2.new(
1,
0
)
camHolder.Position =
UDim2.new(
1,
-30,
0,
20
)
camHolder.BackgroundTransparency =
1
camHolder.ClipsDescendants =
true
camHolder.Parent =
scannerRoot
-- ============================================================
-- CAMERA BOX FACTORY
-- ============================================================
local function makeCamBox(
labelText,
yOffset
)
local box =
Instance.new("Frame")
box.Size =
UDim2.new(
1,
0,
0,
100
)
box.Position =
UDim2.new(
0,
0,
0,
yOffset
)
box.BackgroundColor3 =
DARKTINT
box.BackgroundTransparency =
0.3
box.BorderSizePixel =
0
box.Parent =
camHolder
local stroke =
Instance.new("UIStroke")
stroke.Color =
YELLOW
stroke.Thickness =
1.5
stroke.Parent =
box
local label =
Instance.new("TextLabel")
label.BackgroundTransparency =
1
label.Size =
UDim2.new(
1,
0,
0,
16
)
label.Font =
Enum.Font.Code
label.Text =
labelText
label.TextColor3 =
YELLOW
label.TextSize =
15
label.Parent =
box
local viewport =
Instance.new(
"ViewportFrame"
)
viewport.Size =
UDim2.new(
1,
-6,
1,
-20
)
viewport.Position =
UDim2.new(
0,
3,
0,
18
)
viewport.BackgroundColor3 =
Color3.fromRGB(
28,
34,
42
)
viewport.BackgroundTransparency =
0
viewport.Ambient =
Color3.fromRGB(
190,
205,
220
)
viewport.LightColor =
Color3.fromRGB(
255,
235,
190
)
viewport.ImageColor3 =
Color3.fromRGB(
235,
242,
255
)
viewport.ImageTransparency =
0
viewport.Parent =
box
local worldModel =
Instance.new(
"WorldModel"
)
worldModel.Parent =
viewport
local cam =
Instance.new(
"Camera"
)
cam.FieldOfView =
70
cam.Parent =
viewport
viewport.CurrentCamera =
cam
viewport.Visible =
true
viewport.ZIndex =
2
return {
box = box,
viewport = viewport,
worldModel = worldModel,
camera = cam,
}
end
local thirdPersonCam =
makeCamBox(
"3RD PERSON",
0
)
local firstPersonCam =
makeCamBox(
"1ST PERSON",
110
)
-- ============================================================
-- CAMERA CONNECTION TERMINATION EFFECTS
-- ============================================================
local STATIC_CHARS = " .:*#@%+=-_/\\|"
local function randomStaticLine(width)
local out = table.create(width)
for i = 1, width do
local index = math.random(1, #STATIC_CHARS)
out[i] = STATIC_CHARS:sub(index, index)
end
return table.concat(out)
end
local function makeTerminationOverlay(parent, name)
local overlay = Instance.new("Frame")
overlay.Name = name
overlay.Size = UDim2.fromScale(1, 1)
overlay.Position = UDim2.fromScale(0, 0)
overlay.BackgroundColor3 = Color3.fromRGB(2, 3, 4)
overlay.BackgroundTransparency = 0.04
overlay.BorderSizePixel = 0
overlay.ZIndex = 80
overlay.Visible = false
overlay.ClipsDescendants = true
overlay.Parent = parent
local static = Instance.new("TextLabel")
static.Name = "Static"
static.Size = UDim2.new(1, -12, 1, -12)
static.Position = UDim2.fromOffset(6, 6)
static.BackgroundTransparency = 1
static.Font = Enum.Font.Code
static.TextColor3 = STEEL
static.TextTransparency = 0.18
static.TextSize = 9
static.TextWrapped = false
static.TextXAlignment = Enum.TextXAlignment.Left
static.TextYAlignment = Enum.TextYAlignment.Top
static.ZIndex = 81
static.Parent = overlay
local message = Instance.new("TextLabel")
message.Name = "Message"
message.Size = UDim2.new(1, -20, 0, 44)
message.Position = UDim2.new(0, 10, 0.5, -22)
message.BackgroundTransparency = 1
message.Font = Enum.Font.Code
message.TextColor3 = RED
message.TextSize = 13
message.TextWrapped = true
message.TextXAlignment = Enum.TextXAlignment.Center
message.TextYAlignment = Enum.TextYAlignment.Center
message.TextTransparency = 1
message.ZIndex = 82
message.Parent = overlay
local stroke = Instance.new("UIStroke")
stroke.Color = RED
stroke.Thickness = 1
stroke.Transparency = 1
stroke.Parent = message
return {
root = overlay,
static = static,
message = message,
stroke = stroke,
}
end
playConnectionTerminated = function(effect, displayName, onFinished)
if not effect or not effect.root or not effect.root.Parent then
if onFinished then onFinished() end
return
end
effect.token = (effect.token or 0) + 1
local token = effect.token
effect.root.Visible = true
effect.root.BackgroundTransparency = 0.04
effect.static.TextTransparency = 0.18
effect.message.TextTransparency = 1
effect.stroke.Transparency = 1
task.spawn(function()
for frame = 1, 10 do
if token ~= effect.token or not effect.root.Parent then return end
effect.static.Text = randomStaticLine(42) .. "\n" .. randomStaticLine(42) .. "\n" .. randomStaticLine(42) .. "\n" .. randomStaticLine(42) .. "\n" .. randomStaticLine(42) .. "\n" .. randomStaticLine(42)
effect.static.Rotation = math.random(-1, 1)
effect.root.BackgroundTransparency = math.random(0, 16) / 100
task.wait(0.035)
end
if token ~= effect.token or not effect.root.Parent then return end
effect.static.Text = randomStaticLine(42) .. "\n" .. randomStaticLine(42) .. "\n" .. randomStaticLine(42)
effect.message.Text = "// CONNECTION TERMINATED\n" .. string.upper(displayName or "UNKNOWN")
effect.message.TextTransparency = 0
effect.stroke.Transparency = 0.15
task.wait(0.45)
if token ~= effect.token or not effect.root.Parent then return end
local fade = TweenInfo.new(0.34, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
TweenService:Create(effect.root, fade, {
BackgroundTransparency = 1,
Size = UDim2.new(1, 0, 0, 0),
Position = UDim2.new(0, 0, 0.5, 0),
}):Play()
TweenService:Create(effect.static, fade, {TextTransparency = 1}):Play()
TweenService:Create(effect.message, fade, {TextTransparency = 1}):Play()
TweenService:Create(effect.stroke, fade, {Transparency = 1}):Play()
task.wait(0.36)
if token == effect.token and effect.root.Parent then
effect.root.Visible = false
end
if onFinished then onFinished() end
end)
end
terminateNormalCamera = function(displayName)
if S.normalCameraTermination then return end
local effect = makeTerminationOverlay(camHolder, "NormalCameraTermination")
S.normalCameraTermination = effect
playConnectionTerminated(effect, displayName, function()
if S.normalCameraTermination == effect then
effect.root:Destroy()
S.normalCameraTermination = nil
end
S.trackedPlayer = nil
clearActiveVisual()
clearClones()
setCamsVisible(false)
banner.Text = ""
end)
end
-- ============================================================
-- SPYWARE CAMERA GRID
-- ============================================================
local spywareHolder =
Instance.new("Frame")
spywareHolder.Name =
"SpywareCameras"
spywareHolder.Size =
UDim2.fromOffset(
420,
440
)
spywareHolder.AnchorPoint =
Vector2.new(
1,
0
)
spywareHolder.Position =
UDim2.new(
1,
-30,
0,
20
)
spywareHolder.BackgroundTransparency =
1
spywareHolder.Visible =
false
spywareHolder.Parent =
scannerRoot
local spywareLayout =
Instance.new(
"UIGridLayout"
)
spywareLayout.CellSize =
UDim2.fromOffset(
205,
210
)
spywareLayout.CellPadding =
UDim2.fromOffset(
8,
8
)
spywareLayout.SortOrder =
Enum.SortOrder.LayoutOrder
spywareLayout.Parent =
spywareHolder
-- ============================================================
-- HUD OVERLAP AVOIDANCE
-- ============================================================
local movableHudPanels = {
{
gui = hudTR,
base = UDim2.new(1, -244, 0, 22),
candidates = {
UDim2.new(1, -244, 0, 22),
UDim2.new(0, 24, 0, 150),
UDim2.new(1, -244, 0, 150),
UDim2.new(0, 24, 1, -145),
},
},
{
gui = normalTelemetry,
base = UDim2.new(1, -320, 1, -254),
candidates = {
UDim2.new(1, -320, 1, -254),
UDim2.new(1, -320, 1, -390),
UDim2.new(0, 20, 1, -254),
UDim2.new(0, 20, 1, -145),
UDim2.new(0, 20, 0, 78),
},
},
{
gui = solverSystemPanel,
base = UDim2.new(1, -320, 0, 214),
candidates = {
UDim2.new(1, -320, 0, 214),
UDim2.new(0, 20, 0, 78),
UDim2.new(1, -320, 0, 474),
UDim2.new(0, 20, 1, -190),
},
},
}
local function rectsOverlap(aPos, aSize, bPos, bSize, padding)
padding = padding or 0
return aPos.X - padding < bPos.X + bSize.X
and aPos.X + aSize.X + padding > bPos.X
and aPos.Y - padding < bPos.Y + bSize.Y
and aPos.Y + aSize.Y + padding > bPos.Y
end
local function guiRect(guiObject)
return guiObject.AbsolutePosition, guiObject.AbsoluteSize
end
local function candidateRect(guiObject, candidate)
local parent = guiObject.Parent
local parentPos = parent and parent.AbsolutePosition or Vector2.zero
local parentSize = parent and parent.AbsoluteSize or Vector2.zero
local size = guiObject.AbsoluteSize
local pos = parentPos + Vector2.new(
candidate.X.Scale * parentSize.X + candidate.X.Offset - guiObject.AnchorPoint.X * size.X,
candidate.Y.Scale * parentSize.Y + candidate.Y.Offset - guiObject.AnchorPoint.Y * size.Y
)
return pos, size
end
local fixedHudObstacles = {hudTL, hudBL, hudBR, banner, camHolder, spywareHolder, listPanel}
local function applyHudPanelLayout()
local spyVisible = spywareHolder.Visible
local camsVisible = camHolder.Visible and camHolder.AbsoluteSize.Y > 1
-- Spyware gets a dedicated RIGHT-SIDE lane. The player list owns the
-- upper-left lane, so spyware is never allowed to occupy that rectangle.
-- This is deliberately enforced every layout pass because the player list
-- expands to ~220px tall when opened.
if spyVisible then
local spyCandidates = {
UDim2.new(1, -30, 0, 88),
UDim2.new(1, -30, 0, 116),
UDim2.new(1, -30, 1, -460),
}
local spyChosen = spyCandidates[1]
for _, candidate in ipairs(spyCandidates) do
local pos, size = candidateRect(spywareHolder, candidate)
local blocked = false
for _, fixed in ipairs({listPanel, hudTL, hudBL, hudBR, banner}) do
if fixed ~= spywareHolder and fixed.Visible then
local fpos, fsize = guiRect(fixed)
if rectsOverlap(pos, size, fpos, fsize, 8) then
blocked = true
break
end
end
end
if not blocked then
spyChosen = candidate
break
end
end
spywareHolder.Position = spyChosen
spywareHolder.ZIndex = 2
-- Normal telemetry is removed while the spyware grid is active; there
-- is no reason to let it compete for the remaining screen space.
if normalTelemetry then
normalTelemetry.Visible = false
end
-- The System Override panel is deliberately REMOVED while spyware is
-- active. Do not move it around to make room for the camera grid.
solverSystemPanel.Visible = false
return
end
if normalTelemetry then
normalTelemetry.Visible = true
end
-- When spectating a tracked player, the camera feed owns its space.
-- The Solver System Override panel is simply removed instead of being
-- shuffled around the screen. It will be restored when the camera closes.
if camsVisible then
solverSystemPanel.Visible = false
return
end
-- Normal telemetry lives above the bottom-right status text when there is
-- enough vertical room.
local telemetryCandidates = {
UDim2.new(1, -320, 1, -254),
UDim2.new(0, 20, 1, -254),
UDim2.new(0, 20, 0, 78),
}
local telemetryChosen = telemetryCandidates[1]
for _, candidate in ipairs(telemetryCandidates) do
local pos, size = candidateRect(normalTelemetry, candidate)
local blocked = false
for _, fixed in ipairs({hudTL, hudBL, hudBR, banner, camHolder, solverSystemPanel, listPanel}) do
if fixed ~= normalTelemetry and fixed.Visible then
local fpos, fsize = guiRect(fixed)
if rectsOverlap(pos, size, fpos, fsize, 6) then
blocked = true
break
end
end
end
if not blocked then
telemetryChosen = candidate
break
end
end
normalTelemetry.Position = telemetryChosen
-- Solver override gets its own responsive lane.
local solverCandidates
if camsVisible then
solverCandidates = {
UDim2.new(0, 20, 0, 78),
UDim2.new(0, 20, 1, -190),
UDim2.new(1, -320, 1, -190),
}
else
solverCandidates = {
UDim2.new(1, -320, 0, 214),
UDim2.new(0, 20, 0, 78),
UDim2.new(1, -320, 1, -190),
}
end
local chosen = solverCandidates[1]
for _, candidate in ipairs(solverCandidates) do
local pos, size = candidateRect(solverSystemPanel, candidate)
local blocked = false
for _, fixed in ipairs({hudTL, hudBL, hudBR, banner, camHolder, normalTelemetry, listPanel}) do
if fixed ~= solverSystemPanel and fixed.Visible then
local fpos, fsize = guiRect(fixed)
if rectsOverlap(pos, size, fpos, fsize, 6) then
blocked = true
break
end
end
end
if not blocked then
chosen = candidate
break
end
end
solverSystemPanel.Position = chosen
end
local overlapAccumulator = 0
STATE.connect(RunService.RenderStepped, function(dt)
overlapAccumulator += dt
if overlapAccumulator >= 0.12 then
overlapAccumulator = 0
applyHudPanelLayout()
end
end)
-- Forward declarations because Spyware
-- feeds are created before the normal camera
-- clone functions are declared below.
local buildClone
local cloneEnvironment
local syncPose
-- ============================================================
-- SPYWARE FEED
-- ============================================================
local function createSpywareFeed(
plr,
order
)
local root =
Instance.new("Frame")
root.Name =
"SpyFeed_"
.. plr.Name
root.BackgroundColor3 =
DARKTINT
root.BackgroundTransparency =
0.22
root.BorderSizePixel =
0
root.LayoutOrder =
order
root.Parent =
spywareHolder
local stroke =
Instance.new(
"UIStroke"
)
stroke.Color =
YELLOW
stroke.Thickness =
1.2
stroke.Parent =
root
local title =
Instance.new(
"TextLabel"
)
title.Size =
UDim2.new(
1,
0,
0,
18
)
title.BackgroundTransparency =
1
title.Font =
Enum.Font.Code
title.Text =
"SPYWARE // "
.. plr.Name
title.TextColor3 =
YELLOW
title.TextSize =
11
title.Parent =
root
local third =
makeCamBox(
"3RD",
0
)
third.box.Parent =
root
third.box.Size =
UDim2.new(
0.5,
-3,
1,
-22
)
third.box.Position =
UDim2.new(
0,
2,
0,
20
)
local thirdLabel =
third.box:FindFirstChildOfClass(
"TextLabel"
)
if thirdLabel then
thirdLabel.Text =
"3RD"
thirdLabel.TextSize =
10
end
local first =
makeCamBox(
"1ST",
0
)
first.box.Parent =
root
first.box.Size =
UDim2.new(
0.5,
-3,
1,
-22
)
first.box.Position =
UDim2.new(
0.5,
1,
0,
20
)
local firstLabel =
first.box:FindFirstChildOfClass(
"TextLabel"
)
if firstLabel then
firstLabel.Text =
"1ST"
firstLabel.TextSize =
10
end
local termination = makeTerminationOverlay(root, "ConnectionTermination")
termination.root.ZIndex = 90
return {
plr = plr,
root = root,
third = third,
first = first,
character = nil,
thirdClone = nil,
center = nil,
termination = termination,
terminating = false,
}
end
local function clearSpywareFeeds()
for _, feed in pairs(
S.spywareFeeds
) do
if feed.root then
feed.root:Destroy()
end
end
table.clear(
S.spywareFeeds
)
end
rebuildSpywareFeeds =
function()
clearSpywareFeeds()
if not S.spywareMode then
return
end
for i, plr in ipairs(
S.spywareTargets
) do
if plr
and plr.Parent
then
S.spywareFeeds[plr] =
createSpywareFeed(
plr,
i
)
end
end
end
local function prepareSpywareFeed(
feed,
char
)
if not feed or not char then
return
end
feed.third.worldModel:
ClearAllChildren()
feed.first.worldModel:
ClearAllChildren()
feed.thirdClone =
buildClone(
char,
feed.third.worldModel
)
local hrp =
char:FindFirstChild(
"HumanoidRootPart"
)
feed.center =
hrp
and hrp.Position
or nil
if hrp then
cloneEnvironment(
feed.third.worldModel,
hrp.Position,
90
)
cloneEnvironment(
feed.first.worldModel,
hrp.Position,
90
)
end
feed.character =
char
end
local function updateSpywareFeeds()
if not S.spywareMode then
return
end
for plr, feed in pairs(
S.spywareFeeds
) do
local char =
plr.Character
local hrp =
char
and char:FindFirstChild(
"HumanoidRootPart"
)
local head =
char
and char:FindFirstChild(
"Head"
)
if char
and hrp
and head
and char.Parent
then
if feed.character ~= char
or (
feed.center
and (
hrp.Position
- feed.center
).Magnitude >= 55
)
then
prepareSpywareFeed(
feed,
char
)
end
if feed.thirdClone then
syncPose(
char,
feed.thirdClone
)
local cloneHrp =
feed.thirdClone:
FindFirstChild(
"HumanoidRootPart",
true
)
if cloneHrp then
local target =
cloneHrp.Position
+ Vector3.new(
0,
1.5,
0
)
feed.third.camera.CFrame =
CFrame.lookAt(
target
- cloneHrp.CFrame.LookVector
* 8
+ Vector3.new(
0,
2.1,
0
),
target
)
end
end
feed.first.camera.CFrame =
head.CFrame
* CFrame.new(
0,
0.05,
-0.15
)
feed.third.viewport.BackgroundColor3 =
Color3.fromRGB(
28,
34,
42
)
feed.first.viewport.BackgroundColor3 =
Color3.fromRGB(
28,
34,
42
)
else
feed.third.viewport.BackgroundColor3 =
RED_DIM
feed.first.viewport.BackgroundColor3 =
RED_DIM
end
end
end
-- ============================================================
-- NORMAL CAMERA CLONING
-- ============================================================
buildClone =
function(char, worldModel)
if not char
or not char.Parent
then
return nil
end
local oldArchivable =
char.Archivable
char.Archivable =
true
local ok, clone =
pcall(
function()
return char:Clone()
end
)
char.Archivable =
oldArchivable
if not ok
or not clone
then
warn(
"[MurderDronesHUD] Could not clone character for camera:",
clone
)
return nil
end
for _, inst in ipairs(
clone:GetDescendants()
) do
if inst:IsA("Script")
or inst:IsA("LocalScript")
then
inst:Destroy()
elseif inst:IsA("BasePart") then
inst.Anchored =
true
inst.CanCollide =
false
inst.CanTouch =
false
inst.CanQuery =
false
end
end
local humanoid =
clone:FindFirstChildOfClass(
"Humanoid"
)
if humanoid then
humanoid.DisplayDistanceType =
Enum.HumanoidDisplayDistanceType.None
humanoid.AutoRotate =
false
end
clone.Parent =
worldModel
return clone
end
cloneEnvironment =
function(
worldModel,
centerPosition,
radius
)
local params =
OverlapParams.new()
params.FilterType =
Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances =
{
LocalPlayer.Character
}
local parts =
workspace:GetPartBoundsInRadius(
centerPosition,
radius,
params
)
local cloned = 0
for _, part in ipairs(parts) do
if cloned >= 450 then
break
end
if part:IsA("BasePart")
and part.Transparency < 1
and not (
LocalPlayer.Character
and part:IsDescendantOf(
LocalPlayer.Character
)
)
then
local model =
part:FindFirstAncestorOfClass(
"Model"
)
local isCharacter =
model
and model:FindFirstChildOfClass(
"Humanoid"
)
if not isCharacter then
local oldArchivable =
part.Archivable
part.Archivable =
true
local ok, copy =
pcall(
function()
return part:Clone()
end
)
part.Archivable =
oldArchivable
if ok
and copy
then
for _, inst in ipairs(
copy:GetDescendants()
) do
if inst:IsA("Script")
or inst:IsA("LocalScript")
then
inst:Destroy()
elseif inst:IsA("BasePart") then
inst.Anchored =
true
inst.CanCollide =
false
inst.CanTouch =
false
inst.CanQuery =
false
end
end
copy.Parent =
worldModel
cloned += 1
end
end
end
end
end
clearClones = function()
if S.camClones.third then
S.camClones.third:Destroy()
S.camClones.third = nil
end
if S.camClones.first then
S.camClones.first:Destroy()
S.camClones.first = nil
end
thirdPersonCam.worldModel:
ClearAllChildren()
firstPersonCam.worldModel:
ClearAllChildren()
S.camClones.sourceChar =
nil
S.camClones.environmentCenter =
nil
end
local function refreshClones(char)
clearClones()
S.camClones.third =
buildClone(
char,
thirdPersonCam.worldModel
)
S.camClones.first =
nil
local hrp =
char:FindFirstChild(
"HumanoidRootPart"
)
if hrp then
local center =
hrp.Position
cloneEnvironment(
thirdPersonCam.worldModel,
center,
120
)
cloneEnvironment(
firstPersonCam.worldModel,
center,
120
)
S.camClones.environmentCenter =
center
end
S.camClones.sourceChar =
char
end
syncPose =
function(
originalChar,
cloneChar
)
if not originalChar
or not cloneChar
then
return
end
for _, part in ipairs(
originalChar:GetDescendants()
) do
if part:IsA("BasePart") then
local clonePart =
cloneChar:FindFirstChild(
part.Name,
true
)
if clonePart
and clonePart:IsA(
"BasePart"
)
then
clonePart.CFrame =
part.CFrame
clonePart.Transparency =
part.Transparency
end
end
end
end
setCamsVisible = function(state)
if state == S.camsVisible then
return
end
S.camsVisible =
state
local targetSize =
state
and UDim2.fromOffset(
180,
220
)
or UDim2.fromOffset(
180,
0
)
TweenService:Create(
camHolder,
TweenInfo.new(
0.3,
Enum.EasingStyle.Quad
),
{
Size = targetSize
}
):Play()
camHolder.Visible =
not S.spywareMode
spywareHolder.Visible =
state
and S.spywareMode
and S.solverEnabled
end
-- ============================================================
-- MAIN TRACKING HEARTBEAT
-- ============================================================
STATE.connect(
RunService.Heartbeat,
function()
if S.spywareMode
and S.systemEnabled
and S.solverEnabled
then
updateSpywareFeeds()
end
if S.activeVisual then
S.activeVisual.highlight.Enabled =
S.systemEnabled
S.activeVisual.billboard.Enabled =
S.systemEnabled
end
-- Keep a rolling 10-second history for every player
-- while the tracker is active.
if S.systemEnabled
and os.clock()
- S.lastHistorySample
>= FOOTPRINT_HISTORY_INTERVAL
then
S.lastHistorySample =
os.clock()
for _, plr in ipairs(
Players:GetPlayers()
) do
if plr ~= LocalPlayer then
local char =
plr.Character
local hrp =
char
and char:FindFirstChild(
"HumanoidRootPart"
)
if char
and hrp
and char.Parent
then
addHistorySample(
plr,
char,
hrp
)
end
end
end
end
if S.systemEnabled
and S.trackedPlayer
and S.activeVisual
then
local history =
S.footprintHistory[
S.trackedPlayer
]
if history
and #history > 0
and not S.activeVisual.backtrackSeeded
then
spawnBacktrack(
S.trackedPlayer
)
S.activeVisual.backtrackSeeded =
true
S.activeVisual.lastSpawnedHistoryTime =
history[#history].time
end
if history
and #history > 0
then
local newest =
history[#history]
if newest.time
~= S.activeVisual.lastSpawnedHistoryTime
then
dropFootprint(
newest.ground,
newest.direction,
newest.normal
)
S.activeVisual.lastSpawnedHistoryTime =
newest.time
end
end
end
if S.systemEnabled
and S.trackedPlayer
and not S.spywareMode
then
local char =
S.trackedPlayer.Character
local hrp =
char
and char:FindFirstChild(
"HumanoidRootPart"
)
local head =
char
and char:FindFirstChild(
"Head"
)
if hrp
and head
and char.Parent
then
banner.Text =
"TARGET LOCK :: "
.. S.trackedPlayer.Name
banner.TextColor3 =
YELLOW
setCamsVisible(
true
)
if S.camClones.sourceChar
~= char
or (
S.camClones.environmentCenter
and (
hrp.Position
- S.camClones.environmentCenter
).Magnitude >= 70
)
then
refreshClones(
char
)
end
if S.camClones.third then
syncPose(
char,
S.camClones.third
)
local cloneHrp3 =
S.camClones.third:
FindFirstChild(
"HumanoidRootPart",
true
)
if cloneHrp3 then
local target =
cloneHrp3.Position
+ Vector3.new(
0,
1.5,
0
)
local camPos =
target
- cloneHrp3.CFrame.LookVector
* 9
+ Vector3.new(
0,
2.5,
0
)
thirdPersonCam.camera.CFrame =
CFrame.lookAt(
camPos,
target
)
end
end
firstPersonCam.camera.CFrame =
head.CFrame
* CFrame.new(
0,
0.05,
-0.15
)
else
if not S.normalCameraTermination then
banner.Text =
"SIGNAL LOST // TARGET MISSING"
banner.TextColor3 =
RED
setCamsVisible(
false
)
clearClones()
end
end
elseif S.systemEnabled
and S.spywareMode
and S.solverEnabled
then
banner.Text =
"SOLVER :: SPYWARE // "
.. tostring(
#S.spywareTargets
)
.. " TARGETS"
banner.TextColor3 =
RED
setCamsVisible(
false
)
spywareHolder.Visible =
true
clearClones()
elseif S.solverEnabled then
banner.Text =
"SOLVER :: ACTIVE"
banner.TextColor3 =
YELLOW
setCamsVisible(
false
)
spywareHolder.Visible =
false
clearClones()
else
banner.Text = ""
setCamsVisible(
false
)
spywareHolder.Visible =
false
clearClones()
end
end
)
-- ============================================================
-- SPYWARE MODE
-- ============================================================
local function setSpywareMode(state)
if not S.solverEnabled then
state = false
end
if S.spywareMode == state then
return
end
S.spywareMode =
state
spywareButton.TextColor3 =
state
and RED
or YELLOW_DIM
spywareButton.Text =
state
and "SPYWARE [ON]"
or "SPYWARE [P]"
camHolder.Visible =
not state
spywareHolder.Visible =
state
and S.systemEnabled
and S.solverEnabled
if state then
S.trackedPlayer =
nil
clearActiveVisual()
rebuildSpywareFeeds()
banner.Text =
"SOLVER :: SPYWARE // "
.. tostring(
#S.spywareTargets
)
.. " TARGETS"
else
clearSpywareFeeds()
spywareHolder.Visible =
false
setCamsVisible(
S.systemEnabled
and S.trackedPlayer ~= nil
)
banner.Text =
S.trackedPlayer
and (
"TARGET LOCK :: "
.. S.trackedPlayer.Name
)
or "SOLVER :: ACTIVE"
refreshPlayerButtonColors()
end
end
spywareButton.MouseButton1Click:Connect(
function()
if S.solverEnabled then
setSpywareMode(
not S.spywareMode
)
end
end
)
-- ============================================================
-- AUDIO PLAYBACK
-- ============================================================
playSound =
function(
id,
volume,
speed,
glitch
)
if not id
or id == ""
then
return
end
local s =
Instance.new(
"Sound"
)
s.SoundId =
id
s.Volume =
volume
or 1
s.PlaybackSpeed =
speed
or 1
s.Parent =
SoundService
s:Play()
s.Ended:Connect(
function()
s:Destroy()
end
)
end
-- ============================================================
-- OPEN ANIMATION
-- ============================================================
local function animateOpen()
scannerRoot.Visible =
true
scannerRoot.Position =
UDim2.fromScale(
0,
-0.04
)
tint.BackgroundTransparency =
1
TweenService:Create(
tint,
TweenInfo.new(
0.25
),
{
BackgroundTransparency =
0.88
}
):Play()
TweenService:Create(
scannerRoot,
TweenInfo.new(
0.3,
Enum.EasingStyle.Back,
Enum.EasingDirection.Out
),
{
Position =
UDim2.fromScale(
0,
0
)
}
):Play()
playSound(
OPEN_SOUND_ID,
0.6,
0.92,
true
)
end
-- ============================================================
-- CLOSE ANIMATION
-- ============================================================
local function animateClose()
local tween =
TweenService:Create(
scannerRoot,
TweenInfo.new(
0.2,
Enum.EasingStyle.Quad,
Enum.EasingDirection.In
),
{
Position =
UDim2.fromScale(
0,
-0.04
)
}
)
tween:Play()
TweenService:Create(
tint,
TweenInfo.new(
0.2
),
{
BackgroundTransparency =
1
}
):Play()
playSound(
CLOSE_SOUND_ID,
0.55,
0.82,
true
)
tween.Completed:Connect(
function()
scannerRoot.Visible =
false
end
)
end
local function setSolverEnabled(state)
if S.solverEnabled == state then
if not state then
endSolverScan()
setWingsEnabled(false)
wingsButton.Visible = false
raycastButton.Visible = false
spywareButton.Visible = false
hideSolverScanResult()
solverTelemetry.Visible = false
solverSystemPanel.Visible = false
end
return
end
S.solverEnabled = state
if not state then
endSolverScan()
hideSolverScanResult()
solverTelemetry.Visible = false
solverSystemPanel.Visible = false
setWingsEnabled(false)
S.spywareMode = false
spywareButton.Visible = false
wingsButton.Visible = false
raycastButton.Visible = false
spywareButton.TextColor3 = YELLOW_DIM
spywareButton.Text = "SPYWARE [P]"
table.clear(S.spywareTargets)
for _, feed in pairs(S.spywareFeeds) do
if feed.root then feed.root:Destroy() end
end
table.clear(S.spywareFeeds)
spywareHolder.Visible = false
camHolder.Visible = true
banner.Text = S.trackedPlayer and ("TARGET LOCK :: " .. S.trackedPlayer.Name) or ""
else
spywareButton.Visible = true
wingsButton.Visible = true
raycastButton.Visible = true
raycastButton.Text = "SCAN [R]"
raycastButton.TextColor3 = YELLOW_DIM
raycastStroke.Color = YELLOW_DIM
setWingsEnabled(false)
banner.Text = "X SOLVER :: ACTIVE"
playSound(TARGET_LOCK_SOUND_ID, 0.5, 1.08, true)
end
end
-- ============================================================
-- INPUT
-- ============================================================
STATE.connect(
UserInputService.InputBegan,
function(
input,
gameProcessed
)
if gameProcessed then
return
end
-- M = HUD
if input.KeyCode ==
Enum.KeyCode.M
then
S.systemEnabled =
not S.systemEnabled
if S.systemEnabled then
animateOpen()
else
clearFootprints()
setSolverEnabled(
false
)
animateClose()
end
-- N = Solver
elseif input.KeyCode ==
Enum.KeyCode.N
and S.systemEnabled
then
setSolverEnabled(
not S.solverEnabled
)
-- P = Spyware
elseif input.KeyCode ==
Enum.KeyCode.P
and S.systemEnabled
and S.solverEnabled
then
setSpywareMode(
not S.spywareMode
)
end
end
)
-- First Space jumps from the ground; the next two presses while airborne
-- activate flight when the solver wings are enabled.
STATE.connect(UserInputService.InputBegan, function(input)
if input.KeyCode ~= Enum.KeyCode.Space
or UserInputService:GetFocusedTextBox()
or S.flying
then
return
end
local humanoid = select(1, getFlightRig())
if not humanoid then
return
end
local now = os.clock()
if now - S.lastJumpPress > 1.2 then
S.jumpPressCount = 0
end
S.lastJumpPress = now
if humanoid.FloorMaterial ~= Enum.Material.Air then
S.jumpPressCount = 1
return
end
S.jumpPressCount += 1
if S.jumpPressCount >= 3 and S.wingsEnabled and S.solverEnabled then
S.jumpPressCount = 0
startFlight()
end
end)
-- ============================================================
-- BOOT SEQUENCE
-- ============================================================
local boot =
Instance.new("Frame")
boot.Name =
"BootSequence"
boot.Size =
UDim2.fromScale(
1,
1
)
boot.BackgroundColor3 =
Color3.fromRGB(
4,
7,
9
)
boot.BackgroundTransparency =
0.08
boot.BorderSizePixel =
0
boot.ZIndex =
100
boot.Parent =
gui
local bootTitle =
Instance.new("TextLabel")
bootTitle.Size =
UDim2.fromOffset(
700,
42
)
bootTitle.AnchorPoint =
Vector2.new(
0.5,
0.5
)
bootTitle.Position =
UDim2.fromScale(
0.5,
0.44
)
bootTitle.BackgroundTransparency =
1
bootTitle.Font =
Enum.Font.Code
bootTitle.Text =
"MURDER DRONES // DRONE HUD"
bootTitle.TextColor3 =
YELLOW
bootTitle.TextSize =
26
bootTitle.Parent =
boot
local bootStatus =
Instance.new("TextLabel")
bootStatus.Size =
UDim2.fromOffset(
700,
28
)
bootStatus.AnchorPoint =
Vector2.new(
0.5,
0.5
)
bootStatus.Position =
UDim2.fromScale(
0.5,
0.51
)
bootStatus.BackgroundTransparency =
1
bootStatus.Font =
Enum.Font.Code
bootStatus.Text =
"INITIALIZING..."
bootStatus.TextColor3 =
STEEL
bootStatus.TextSize =
13
bootStatus.Parent =
boot
local bootLine =
Instance.new("Frame")
bootLine.Size =
UDim2.fromOffset(
440,
2
)
bootLine.AnchorPoint =
Vector2.new(
0.5,
0.5
)
bootLine.Position =
UDim2.fromScale(
0.5,
0.56
)
bootLine.BackgroundColor3 =
YELLOW
bootLine.BorderSizePixel =
0
bootLine.Parent =
boot
playSound(
INIT_SOUND_ID,
0.65,
0.9,
true
)
task.spawn(
function()
for _, text in ipairs({
"CONNECTING TO DRONE NETWORK...",
"LOADING NEURAL LINK...",
"CALIBRATING OPTICAL SENSORS // 03...",
"CORE LINK ESTABLISHED // READY",
}) do
if not boot.Parent then
return
end
bootStatus.Text =
text
task.wait(
0.24
)
end
TweenService:Create(
bootTitle,
TweenInfo.new(
0.45,
Enum.EasingStyle.Quad,
Enum.EasingDirection.Out
),
{
TextTransparency =
1
}
):Play()
TweenService:Create(
bootStatus,
TweenInfo.new(
0.45,
Enum.EasingStyle.Quad,
Enum.EasingDirection.Out
),
{
TextTransparency =
1
}
):Play()
TweenService:Create(
bootLine,
TweenInfo.new(
0.45,
Enum.EasingStyle.Quad,
Enum.EasingDirection.Out
),
{
BackgroundTransparency =
1
}
):Play()
local fade =
TweenService:Create(
boot,
TweenInfo.new(
0.55,
Enum.EasingStyle.Quad,
Enum.EasingDirection.Out
),
{
BackgroundTransparency =
1
}
)
fade:Play()
fade.Completed:Wait()
if boot.Parent then
boot:Destroy()
end
end
)
STATE.onCleanup(
function()
if boot then
boot:Destroy()
end
end
)
-- ============================================================
-- DEATH SCREEN
-- ============================================================
local deathFrame =
Instance.new("Frame")
deathFrame.Name =
"DeathRoot"
deathFrame.Size =
UDim2.new(
1,
0,
1,
0
)
deathFrame.BackgroundTransparency =
1
deathFrame.Visible =
false
deathFrame.ZIndex =
50
deathFrame.Parent =
gui
local overlay =
Instance.new("Frame")
overlay.Size =
UDim2.new(
1,
0,
1,
0
)
overlay.BackgroundColor3 =
DEATH_BG
overlay.BackgroundTransparency =
1
overlay.BorderSizePixel =
0
overlay.ZIndex =
50
overlay.Parent =
deathFrame
local logFrame =
Instance.new("Frame")
logFrame.Size =
UDim2.new(
1,
-40,
0,
120
)
logFrame.Position =
UDim2.new(
0,
20,
0,
20
)
logFrame.BackgroundTransparency =
1
logFrame.ZIndex =
51
logFrame.Parent =
overlay
local prompt =
Instance.new("TextLabel")
prompt.Size =
UDim2.new(
1,
-40,
0,
30
)
prompt.Position =
UDim2.new(
0,
20,
1,
-50
)
prompt.BackgroundTransparency =
1
prompt.Text =
"WOULD YOU LIKE TO SEND AN ERROR REPORT?"
prompt.TextColor3 =
Color3.fromRGB(
140,
40,
50
)
prompt.TextTransparency =
1
prompt.Font =
Enum.Font.Code
prompt.TextSize =
13
prompt.TextXAlignment =
Enum.TextXAlignment.Left
prompt.ZIndex =
51
prompt.Parent =
overlay
local deathLoopToken =
0
local function showDeathScreen()
deathLoopToken += 1
local myToken =
deathLoopToken
StarterGui:SetCoreGuiEnabled(
Enum.CoreGuiType.All,
false
)
for _, c in ipairs(
logFrame:GetChildren()
) do
c:Destroy()
end
deathFrame.Visible =
true
overlay.BackgroundTransparency =
1
prompt.TextTransparency =
1
TweenService:Create(
overlay,
TweenInfo.new(
0.42,
Enum.EasingStyle.Quart,
Enum.EasingDirection.Out
),
{
BackgroundTransparency =
0.08
}
):Play()
local headerLine =
Instance.new(
"TextLabel"
)
headerLine.Size =
UDim2.new(
1,
-40,
0,
28
)
headerLine.Position =
UDim2.new(
0,
20,
0,
-4
)
headerLine.BackgroundTransparency =
1
headerLine.Text =
"! DRONE RECOVERY // CORE FAILURE"
headerLine.TextColor3 =
RED
headerLine.TextTransparency =
0.08
headerLine.Font =
Enum.Font.Code
headerLine.TextSize =
16
headerLine.TextXAlignment =
Enum.TextXAlignment.Left
headerLine.ZIndex =
51
headerLine.Parent =
logFrame
local logLines = {
"DIAGNOSTIC HANDSHAKE ACCEPTED...",
"MATERIAL FORM :: UNSTABLE",
"ABSOLUTE SOLVER ACCESS :: DENIED",
"BACKUP CORE :: RESTORE QUEUED",
}
for i, line in ipairs(
logLines
) do
local label =
Instance.new(
"TextLabel"
)
label.Size =
UDim2.new(
1,
0,
0,
22
)
label.Position =
UDim2.new(
0,
0,
0,
26
+ (i - 1) * 22
)
label.BackgroundTransparency =
1
label.Text =
""
label.TextColor3 =
(i == #logLines)
and RED
or STEEL
label.TextTransparency =
(i == #logLines)
and 0.12
or 0.3
label.Font =
Enum.Font.Code
label.TextSize =
12
label.TextXAlignment =
Enum.TextXAlignment.Left
label.ZIndex =
51
label.Parent =
logFrame
task.delay(
0.16
+ (i - 1) * 0.18,
function()
if myToken
~= deathLoopToken
then
return
end
for j = 1, #line do
if not label.Parent
or myToken
~= deathLoopToken
then
break
end
label.Text =
string.sub(
line,
1,
j
)
task.wait(
0.012
)
end
end
)
end
local statusPanel =
Instance.new(
"Frame"
)
statusPanel.Size =
UDim2.new(
0,
360,
0,
82
)
statusPanel.Position =
UDim2.new(
0,
20,
0,
142
)
statusPanel.BackgroundColor3 =
Color3.fromRGB(
12,
14,
17
)
statusPanel.BackgroundTransparency =
0.2
statusPanel.BorderSizePixel =
0
statusPanel.ZIndex =
51
statusPanel.Parent =
overlay
local statusStroke =
Instance.new(
"UIStroke"
)
statusStroke.Color =
RED_DIM
statusStroke.Thickness =
1
statusStroke.Transparency =
0.2
statusStroke.Parent =
statusPanel
local status =
Instance.new(
"TextLabel"
)
status.Size =
UDim2.new(
1,
-18,
0,
30
)
status.Position =
UDim2.new(
0,
9,
0,
8
)
status.BackgroundTransparency =
1
status.Text =
"CORE STATUS :: OFFLINE"
status.TextColor3 =
RED
status.TextTransparency =
0.05
status.Font =
Enum.Font.Code
status.TextSize =
19
status.TextXAlignment =
Enum.TextXAlignment.Left
status.ZIndex =
52
status.Parent =
statusPanel
local subStatus =
Instance.new(
"TextLabel"
)
subStatus.Size =
UDim2.new(
1,
-18,
0,
22
)
subStatus.Position =
UDim2.new(
0,
9,
0,
42
)
subStatus.BackgroundTransparency =
1
subStatus.Text =
"REBOOTING SENSOR ARRAY..."
subStatus.TextColor3 =
STEEL
subStatus.TextTransparency =
0.15
subStatus.Font =
Enum.Font.Code
subStatus.TextSize =
11
subStatus.TextXAlignment =
Enum.TextXAlignment.Left
subStatus.ZIndex =
52
subStatus.Parent =
statusPanel
local bars = {}
for i = 1, 5 do
local bar =
Instance.new(
"Frame"
)
bar.Size =
UDim2.new(
1,
0,
0,
1
)
bar.Position =
UDim2.new(
0,
0,
0,
250
+ i * 52
)
bar.BackgroundColor3 =
(i % 2 == 0)
and YELLOW_DIM
or RED_DIM
bar.BackgroundTransparency =
0.82
bar.BorderSizePixel =
0
bar.ZIndex =
50
bar.Parent =
overlay
table.insert(
bars,
bar
)
end
task.spawn(
function()
while myToken
== deathLoopToken
and deathFrame.Visible
do
for _, bar in ipairs(
bars
) do
if myToken
~= deathLoopToken
then
break
end
local startY =
bar.Position.Y.Offset
bar.Position =
UDim2.new(
0,
0,
0,
startY - 10
)
TweenService:Create(
bar,
TweenInfo.new(
0.7,
Enum.EasingStyle.Linear
),
{
Position =
UDim2.new(
0,
0,
0,
startY + 10
)
}
):Play()
end
task.wait(
0.75
)
end
end
)
task.delay(
0.6,
function()
if myToken
~= deathLoopToken
then
return
end
TweenService:Create(
prompt,
TweenInfo.new(
0.35
),
{
TextTransparency =
0.45
}
):Play()
end
)
if LocalPlayer.Character then
LocalPlayer.CharacterAdded:Wait()
end
if myToken
~= deathLoopToken
then
return
end
TweenService:Create(
overlay,
TweenInfo.new(
0.55,
Enum.EasingStyle.Quad,
Enum.EasingDirection.In
),
{
BackgroundTransparency =
1
}
):Play()
task.delay(
0.6,
function()
if myToken
~= deathLoopToken
then
return
end
deathFrame.Visible =
false
StarterGui:SetCoreGuiEnabled(
Enum.CoreGuiType.All,
true
)
if statusPanel then
statusPanel:Destroy()
end
for _, bar in ipairs(
bars
) do
if bar then
bar:Destroy()
end
end
end
)
end
STATE.onCleanup(
function()
StarterGui:SetCoreGuiEnabled(
Enum.CoreGuiType.All,
true
)
end
)
local function hookDeath(
plr,
char
)
local humanoid =
char:WaitForChild(
"Humanoid",
5
)
if not humanoid then
return
end
STATE.connect(
humanoid.Died,
showDeathScreen
)
end
if LocalPlayer.Character then
hookDeath(
LocalPlayer,
LocalPlayer.Character
)
end
STATE.connect(
LocalPlayer.CharacterAdded,
function(char)
hookDeath(
LocalPlayer,
char
)
end
)
-- ============================================================
-- CLEANUP
-- ============================================================
STATE.onCleanup(
function()
setSolverEnabled(
false
)
clearActiveVisual()
clearClones()
clearSpywareFeeds()
clearTail()
end
)
print(
"MurderDronesHUD v18.13 // ABSOLUTE SOLVER // DOUBLE CATALOG WINGS // POP DEPLOY // AUTONOMOUS TAIL // CAMERA-SAFE HUD"
)Features & Information
Player tracking, visible foot trail backing to ten seconds, first / third person view of up to six players at once, non-FE (Meaning only you can see it) wings, raycast for dark areas
ENTIRELY vibe-coded. Please tell me if there are any issues you come across while using this. Universal script, put it for baseplate because universal requires an image and at the time of posting, that feature isn't fucntional.
Community Comments (0)
No comments yet for this script.


