Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF - Verified script for Sniper Arena
Key Required

Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF

Sniper Arenascriptsforgamesscriptsforgames 1.8K views 5.3K executesUpdated Oct 9, 2026
Unrated
00
Lua Script•1278 lines (42522 chars)
--[[
If you enjoy the script, please consider liking the post.
It helps motivate me to release more open-source scripts
and keep existing ones updated.

]]

local StarterGui = game:GetService("StarterGui")

local function notify(title, message, duration)
	local details = {
		Title = title,
		Text = message,
		Duration = duration,
		Button1 = "OK",
	}

	for _ = 1, 8 do
		if pcall(StarterGui.SetCore, StarterGui, "SendNotification", details) then
			return
		end
		task.wait(0.25)
	end
	warn(title .. ": " .. message)
end

local environmentGetter = getgenv
local executorDebug = debug
local missing = {}

if type(environmentGetter) ~= "function" then
	table.insert(missing, "getgenv")
end
for _, name in { "getupvalues", "getupvalue", "setupvalue" } do
	if type(executorDebug) ~= "table" or type(executorDebug[name]) ~= "function" then
		table.insert(missing, "debug." .. name)
	end
end

if #missing > 0 then
	notify("Executor APIs Missing", "Required: " .. table.concat(missing, ", "), 20)
	return
end

local environmentOk, environment = pcall(function()
	return environmentGetter()
end)
if not environmentOk then
	notify("Executor APIs Missing", "getgenv() failed: " .. tostring(environment), 20)
	return
end
if type(environment) ~= "table" then
	notify("Executor APIs Missing", "getgenv() did not return a table.", 20)
	return
end

local upvalues = executorDebug.getupvalues
local getupvalue = executorDebug.getupvalue
local setupvalue = executorDebug.setupvalue

local previous = environment.__aimSession
if previous then
	assert(type(previous.unload) == "function", "Existing shooting hook cannot be unloaded")
	local success, reason = pcall(previous.unload, true)
	assert(success and environment.__aimSession ~= previous,
		"Could not unload the existing shooting hook: " .. tostring(reason))
end

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")

local ClientShootable = require(ReplicatedStorage.Client.CombatController.ClientComponent.ClientShootableComponent)
local CombatController = require(ReplicatedStorage.Client.CombatController)
local CommonWeapon = require(ReplicatedStorage.Common.CombatService.CommonWeapon)
local Entities = require(ReplicatedStorage.Remote.EntityService)
local HumanoidEntity = require(ReplicatedStorage.Remote.EntityService.Entity.HumanoidEntity)
local Collision = require(ReplicatedStorage.Constant).Collision
local Combat = require(ReplicatedStorage.Config.Config).Combat

local originalShoot = ClientShootable.Shoot
local localShoot = ClientShootable.LocalShoot
assert(type(originalShoot) == "function" and type(localShoot) == "function",
	"The game's shooting functions are unavailable")

local originIndex, originalOrigin
for index, value in upvalues(originalShoot) do
	if type(value) == "function" then
		assert(originIndex == nil, "The weapon has more than one origin function")
		originIndex, originalOrigin = index, value
	end
end
assert(originIndex ~= nil, "The weapon's origin function was not found")

local localOriginMatches = 0
for _, value in upvalues(localShoot) do
	if value == originalOrigin then
		localOriginMatches += 1
	end
end
assert(localOriginMatches == 1, "LocalShoot uses a different combat origin")

local CONE_DOT = math.cos(math.rad(15))
local FIRE_INPUT = "trigger"
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.RespectCanCollide = false

local state = {
	active = true,
	enabled = true,
	triggerbot = false,
	heldWeapon = nil,
	triggerConnection = nil,
	selectedEntity = nil,
	selectedAt = -math.huge,
	preparedShot = nil,
	connections = {},
	reportedSelectionError = false,
	menuKey = Enum.KeyCode.RightShift,
	aimKey = Enum.KeyCode.V,
	triggerKey = Enum.KeyCode.T,
	deviceLabel = "Mobile",
	uiVisible = true,
	lockMouse = true,
	uiSync = nil :: (() -> ())?,
	uiDestroy = nil :: (() -> ())?,
}

local HEAD_POINTS = {
	Vector3.new(0, 0, 0),
	Vector3.new(0, 0.36, 0),
	Vector3.new(-0.36, 0, 0),
	Vector3.new(0.36, 0, 0),
	Vector3.new(0, -0.36, 0),
	Vector3.new(-0.3, 0.3, 0),
	Vector3.new(0.3, 0.3, 0),
	Vector3.new(-0.3, -0.3, 0),
	Vector3.new(0.3, -0.3, 0),
}

local BODY_PARTS = {
	Body = true, Torso = true, UpperTorso = true, LowerTorso = true,
	Arm = true, LeftArm = true, RightArm = true,
	LeftUpperArm = true, LeftLowerArm = true, LeftHand = true,
	RightUpperArm = true, RightLowerArm = true, RightHand = true,
	LeftLeg = true, RightLeg = true,
	LeftUpperLeg = true, LeftLowerLeg = true, LeftFoot = true,
	RightUpperLeg = true, RightLowerLeg = true, RightFoot = true,
}

local function inspectPoint(model, part, point, origin, view, headOnly)
	local offset = point - origin
	local distance = offset.Magnitude
	if distance <= 0.01 or distance > Combat.BulletMaxDistance
		or view:Dot(offset.Unit) < CONE_DOT then
		return nil
	end

	local hit = workspace:Raycast(origin, offset, rayParams)
	if headOnly then
		if hit and hit.Instance == part then
			return point, distance, part
		end
	elseif not hit or hit.Instance:IsDescendantOf(model) then
		return point, distance, part
	end
	return nil
end

local function visiblePoint(entity, origin, view)
	local model = entity:GetModel()
	if not model or not model:IsDescendantOf(workspace) then
		return nil
	end

	local head = model:FindFirstChild("Head", true)
	if head and head:IsA("BasePart") then
		local frame, size = head.CFrame, head.Size
		for _, sample in HEAD_POINTS do
			local point = frame:PointToWorldSpace(Vector3.new(
				sample.X * size.X, sample.Y * size.Y, sample.Z * size.Z
			))
			local aimPoint, distance, part = inspectPoint(model, head, point, origin, view, true)
			if aimPoint then
				return aimPoint, distance, part
			end
		end
	end

	local body = entity:GetBodyPart()
	local root = entity:GetRootPart()
	for _, part in { body, root } do
		if part and part ~= head and part:IsA("BasePart") then
			local aimPoint, distance, hitPart = inspectPoint(model, part, part.Position, origin, view, false)
			if aimPoint then
				return aimPoint, distance, hitPart
			end
		end
	end

	for _, part in model:GetDescendants() do
		if part:IsA("BasePart") and BODY_PARTS[part.Name] and part ~= body and part ~= root then
			local aimPoint, distance, hitPart = inspectPoint(model, part, part.Position, origin, view, false)
			if aimPoint then
				return aimPoint, distance, hitPart
			end
		end
	end
	return nil
end

local function acquireTarget(origin, view)
	local self = Entities.GetLocalEntity()
	if not self or not self:IsAlive() then
		return nil
	end
	local group = self:GetCollision(Collision.Attack)
	if type(group) ~= "string" then
		return nil
	end

	rayParams.CollisionGroup = group
	local character = self:GetWorkspaceRoot()
	rayParams.FilterDescendantsInstances = character and { character } or {}

	local function isHostile(entity)
		return entity ~= self and HumanoidEntity:is(entity)
			and entity:IsAlive() and not self:IsFriendly(entity)
	end

	if state.selectedEntity and os.clock() - state.selectedAt <= 0.22
		and isHostile(state.selectedEntity) then
		local point, distance, part = visiblePoint(state.selectedEntity, origin, view)
		if point then
			return state.selectedEntity, point, distance, part
		end
	end

	local closestEntity, closestPoint, closestDistance, closestPart
	closestDistance = Combat.BulletMaxDistance
	for _, entity in Entities.Entity.GetAll() do
		if isHostile(entity) then
			local point, distance, part = visiblePoint(entity, origin, view)
			if point and distance < closestDistance then
				closestEntity, closestPoint, closestDistance, closestPart = entity, point, distance, part
			end
		end
	end
	return closestEntity, closestPoint, closestDistance, closestPart
end

local function reportSelectionError(reason)
	if not state.reportedSelectionError then
		state.reportedSelectionError = true
		warn("Target selection failed: " .. tostring(reason))
	end
end

local function redirectedOrigin(...)
	local origin, detectedAt, cameraData = originalOrigin(...)
	if not (state.active and state.enabled and typeof(origin) == "CFrame") then
		return origin, detectedAt, cameraData
	end

	if state.preparedShot == false then
		return origin, detectedAt, cameraData
	end

	local entity, point
	if state.preparedShot then
		entity, point = state.preparedShot.entity, state.preparedShot.point
	else
		local success, selected, selectedPoint = pcall(acquireTarget, origin.Position, origin.LookVector)
		if not success then
			reportSelectionError(selected)
			return origin, detectedAt, cameraData
		end
		entity, point = selected, selectedPoint
	end

	if not point then
		return origin, detectedAt, cameraData
	end
	local offset = point - origin.Position
	if offset.Magnitude <= 0.001 or origin.LookVector:Dot(offset.Unit) < CONE_DOT then
		return origin, detectedAt, cameraData
	end

	state.selectedEntity = entity
	state.selectedAt = os.clock()
	return CFrame.lookAt(origin.Position, point), detectedAt, cameraData
end

local function runOriginalShoot(component, start, direction, context, prepared)
	state.preparedShot = prepared
	local success, result = pcall(originalShoot, component, start, direction, context)
	state.preparedShot = nil
	if not success then
		error(result, 0)
	end
	return result
end

local function shootWithTarget(component, start, direction, context)
	if not (state.active and state.enabled) then
		return originalShoot(component, start, direction, context)
	end

	local success, origin = pcall(originalOrigin)
	if not success or typeof(origin) ~= "CFrame" then
		return runOriginalShoot(component, start, direction, context, false)
	end

	local selected, entity, point, _, part = pcall(acquireTarget, origin.Position, origin.LookVector)
	if not selected then
		reportSelectionError(entity)
		return runOriginalShoot(component, start, direction, context, false)
	end
	if not entity or not point then
		return runOriginalShoot(component, start, direction, context, false)
	end

	local pivot = entity:GetPivot(true)
	local offset = point - origin.Position
	if not pivot or offset.Magnitude <= 0.001 or origin.LookVector:Dot(offset.Unit) < CONE_DOT then
		return runOriginalShoot(component, start, direction, context, false)
	end

	local shotContext = context or {}
	shotContext.Target = entity.Instance
	shotContext.TargetPos = pivot:PointToObjectSpace(point)
	shotContext.TargetHeadshot = part ~= nil and part.Name == "Head"
	return runOriginalShoot(component, start, direction, shotContext, { entity = entity, point = point })
end

local function releaseTrigger()
	local held = state.heldWeapon
	state.heldWeapon = nil
	if held then
		local shooter = held._Shootable
		if shooter and shooter.StopShootingTimer then
			local success, reason = pcall(shooter.StopShootingTimer, shooter, { Input = FIRE_INPUT })
			if not success then
				warn("Could not stop firing: " .. tostring(reason))
			end
		end
	end
end

local function hasTargetInCrosshair(entity, origin)
	local model = entity:GetModel()
	if not model then
		return false
	end
	local hit = workspace:Raycast(origin.Position, origin.LookVector * Combat.BulletMaxDistance, rayParams)
	return hit ~= nil and hit.Instance:IsDescendantOf(model)
end

local function checkTrigger()
	if not state.active or not state.triggerbot then
		releaseTrigger()
		return
	end

	if UserInputService:GetFocusedTextBox() or UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
		releaseTrigger()
		return
	end

	local weapon = CombatController.GetWeapon()
	local shooter = weapon and weapon._Shootable
	if not (weapon and weapon.Activated and shooter and not shooter.Destroyed) then
		releaseTrigger()
		return
	end

	local origin = originalOrigin()
	if typeof(origin) ~= "CFrame" then
		releaseTrigger()
		return
	end

	local entity = acquireTarget(origin.Position, origin.LookVector)
	if not entity or (not state.enabled and not hasTargetInCrosshair(entity, origin)) then
		releaseTrigger()
		return
	end

	local automatic = shooter:IsFullAuto()
	if state.heldWeapon and (state.heldWeapon ~= weapon or not automatic) then
		releaseTrigger()
	end
	if automatic then
		if state.heldWeapon then
			return
		end
		if not (shooter:CanShoot() and shooter:CanShootNow()) then
			return
		end
		if weapon:CanAction(CommonWeapon.Action.Primary) then
			if CombatController.PrimaryAction.Begin(FIRE_INPUT) then
				state.heldWeapon = weapon
			end
		end
		return
	end

	if shooter:CanShoot() and shooter:CanShootNow() and weapon:CanAction(CommonWeapon.Action.Primary) then
		CombatController.PrimaryAction.Begin(FIRE_INPUT)
	end
end

local function runTrigger()
	local success, reason = pcall(checkTrigger)
	if not success then
		state.triggerbot = false
		local sync = state.uiSync
		if sync then
			sync()
		end
		if state.triggerConnection then
			state.triggerConnection:Disconnect()
			state.triggerConnection = nil
		end
		releaseTrigger()
		warn("Triggerbot stopped: " .. tostring(reason))
		notify("Triggerbot", "Stopped: " .. tostring(reason), 8)
	end
end

local function setTriggerbot(enabled)
	state.triggerbot = enabled
	if enabled then
		if not state.triggerConnection then
			state.triggerConnection = RunService.Heartbeat:Connect(runTrigger)
		end
	else
		if state.triggerConnection then
			state.triggerConnection:Disconnect()
			state.triggerConnection = nil
		end
		releaseTrigger()
	end
end

local deviceReport

local function restoreDeviceReport()
	local saved = deviceReport
	if not saved then
		return
	end
	deviceReport = nil
	if saved.connection then saved.connection:Disconnect() end

	local actualDevice = saved.input.Device
	if type(actualDevice) == "string" and actualDevice ~= state.deviceLabel then
		local ok, reason = pcall(function()
			saved.remote:FireServer(actualDevice)
		end)
		if not ok then
			warn("Could not restore device report: " .. tostring(reason))
		end
	end
end

local function enableDeviceReport()
	if deviceReport then
		return
	end
	local input = require(ReplicatedStorage.Client.InputHelper)
	local devices = require(ReplicatedStorage.Constant).Device
	local remote = ReplicatedStorage.Remote.Any.Device
	local changed = input.Event and input.Event.DeviceChanged
	assert(changed and type(changed.Connect) == "function", "DeviceChanged signal is unavailable")
	assert(type(remote.FireServer) == "function", "Device reporting is unavailable")
	assert(type(devices[state.deviceLabel]) == "string", "Reported device is unavailable")

	local saved = {
		input = input, remote = remote, devices = devices,
		warned = false, report = function() end,
		connection = nil :: RBXScriptConnection?,
	}
	local function report()
		if not state.active or deviceReport ~= saved then
			return
		end
		local ok, reason = pcall(function()
			remote:FireServer(devices[state.deviceLabel])
		end)
		if not ok and not saved.warned then
			saved.warned = true
			warn("Could not report device: " .. tostring(reason))
		end
	end
	saved.report = report
	saved.connection = changed:Connect(report)
	deviceReport = saved
	report()
end

local function buildPanel()
	local player = Players.LocalPlayer
	local playerGui = player and player:WaitForChild("PlayerGui", 5)
	assert(playerGui, "PlayerGui is unavailable")

	local colour = {
		base = Color3.fromRGB(23, 27, 33),
		inner = Color3.fromRGB(31, 36, 44),
		raised = Color3.fromRGB(43, 50, 60),
		border = Color3.fromRGB(73, 82, 95),
		text = Color3.fromRGB(241, 244, 247),
		muted = Color3.fromRGB(153, 164, 177),
		accent = Color3.fromRGB(85, 207, 173),
		active = Color3.fromRGB(31, 78, 69),
		alert = Color3.fromRGB(226, 120, 115),
	}
	local images = {
		main = "rbxassetid://83752373575368",
		settings = "rbxassetid://106205298246017",
		minimise = "rbxassetid://95070996149109",
		power = "rbxassetid://89331085993646",
		check = "rbxassetid://86817768619372",
	}
	local controls = {}
	local bindings = {}
	local uiConnections = {}
	local activePress = nil
	local capturing = nil :: string?
	local dragging = nil
	local pointerStart = Vector2.zero
	local popupOpen = false
	local cursor = { bound = false, behavior = Enum.MouseBehavior.Default, iconVisible = true }
	local cursorStep = "ys.menu.cursor." .. tostring(player.UserId)

	local function connect(signal, callback)
		local connection = signal:Connect(callback)
		table.insert(uiConnections, connection)
		return connection
	end

	local function create(class, parent, values)
		local item = Instance.new(class)
		for key, value in values do
			item[key] = value
		end
		item.Parent = parent
		return item
	end

	local function round(parent, radius)
		create("UICorner", parent, { CornerRadius = UDim.new(0, radius) })
	end

	local function icon(parent, image, x, y, size, tint, z)
		return create("ImageLabel", parent, {
			BackgroundTransparency = 1, Image = image, ImageColor3 = tint or colour.muted,
			Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(size, size),
			ScaleType = Enum.ScaleType.Fit, ZIndex = z or 1,
		})
	end

	local function label(parent, content, x, y, width, height, size, tint, bold)
		return create("TextLabel", parent, {
			BackgroundTransparency = 1, Text = content, TextSize = size,
			Font = bold and Enum.Font.GothamBold or Enum.Font.GothamMedium,
			TextColor3 = tint or colour.text, TextXAlignment = Enum.TextXAlignment.Left,
			TextYAlignment = Enum.TextYAlignment.Center,
			TextTruncate = Enum.TextTruncate.AtEnd,
			Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(width, height),
		})
	end

	local screen = create("ScreenGui", playerGui, {
		Name = "YSHub", ResetOnSpawn = false, IgnoreGuiInset = false,
		ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 10000,
	})
	local uiRoot = gethui
	if type(uiRoot) == "function" then
		local ok, root = pcall(uiRoot)
		if ok and typeof(root) == "Instance" then
			pcall(function() screen.Parent = root end)
		end
	end
	local modal = create("TextButton", screen, {
		Name = "MouseInput", Text = "", BackgroundTransparency = 1,
		AutoButtonColor = false, Modal = true, Active = true, ZIndex = 0,
		Size = UDim2.fromScale(1, 1), Visible = false,
	})
	local function releaseMouse()
		modal.Visible = false
		if not cursor.bound then return end
		RunService:UnbindFromRenderStep(cursorStep)
		cursor.bound = false
		-- The Roblox pause menu owns the cursor while it is open.
		if not GuiService.MenuIsOpen then
			if UserInputService.MouseBehavior == Enum.MouseBehavior.Default then
				UserInputService.MouseBehavior = cursor.behavior
			end
			UserInputService.MouseIconEnabled = cursor.iconVisible
		end
		cursor.behavior = Enum.MouseBehavior.Default
		cursor.iconVisible = true
	end
	local function updateMouse()
		local useCursor = state.active and state.uiVisible and state.lockMouse
			and not GuiService.MenuIsOpen
		if not useCursor then
			releaseMouse()
			return
		end
		modal.Visible = true
		if cursor.bound then return end
		cursor.behavior = UserInputService.MouseBehavior
		cursor.iconVisible = UserInputService.MouseIconEnabled
		cursor.bound = true
		RunService:BindToRenderStep(cursorStep, Enum.RenderPriority.Last.Value + 1, function()
			if not (state.active and state.uiVisible and state.lockMouse) or GuiService.MenuIsOpen then
				return
			end
			UserInputService.MouseBehavior = Enum.MouseBehavior.Default
			UserInputService.MouseIconEnabled = true
		end)
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
		UserInputService.MouseIconEnabled = true
	end
	state.uiDestroy = function()
		releaseMouse()
		for _, connection in uiConnections do connection:Disconnect() end
		state.uiSync = nil
		state.uiDestroy = nil
		screen:Destroy()
	end
	local window = create("Frame", screen, {
		Name = "Window", AnchorPoint = Vector2.new(0.5, 0.5),
		Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(376, 472),
		BackgroundColor3 = colour.base, BorderSizePixel = 0, Active = true,
	})
	round(window, 9)
	create("UIStroke", window, {
		Color = colour.border, Thickness = 1,
		ApplyStrokeMode = Enum.ApplyStrokeMode.Border,
		BorderStrokePosition = Enum.BorderStrokePosition.Inner,
	})
	local scaler = create("UIScale", window, { Scale = 1 })

	local function resize()
		local camera = workspace.CurrentCamera
		local view = camera and camera.ViewportSize or Vector2.new(1280, 720)
		scaler.Scale = math.min(1, (view.X - 16) / 376, (view.Y - 24) / 472)
	end
	resize()

	local header = create("Frame", window, {
		BackgroundTransparency = 1, Position = UDim2.fromOffset(16, 9),
		Size = UDim2.fromOffset(344, 49), Active = true,
	})
	label(header, "YS HUB", 1, 0, 214, 26, 18, colour.text, true)
	label(header, "SNIPER ARENA  /  AIM & FIRE", 1, 27, 275, 14, 10, colour.muted)
	local minimise = create("TextButton", header, {
		Name = "Hide", Text = "", AutoButtonColor = false,
		BackgroundColor3 = colour.inner, BorderSizePixel = 0,
		Position = UDim2.fromOffset(302, 3), Size = UDim2.fromOffset(38, 38),
	})
	round(minimise, 6)
	icon(minimise, images.minimise, 10, 10, 18, colour.text)
	create("Frame", window, {
		Position = UDim2.fromOffset(12, 63), Size = UDim2.fromOffset(352, 1),
		BorderSizePixel = 0, BackgroundColor3 = colour.raised,
	})
	create("Frame", window, {
		Position = UDim2.fromOffset(107, 80), Size = UDim2.fromOffset(1, 342),
		BorderSizePixel = 0, BackgroundColor3 = colour.raised,
	})

	local pages = {}
	local tabs = {}
	for index, name in { "Main", "Settings" } do
		local y = 89 + (index - 1) * 48
		local tab = create("TextButton", window, {
			Name = name .. "Tab", Text = "", AutoButtonColor = false,
			BackgroundColor3 = colour.base, BorderSizePixel = 0,
			Position = UDim2.fromOffset(12, y), Size = UDim2.fromOffset(85, 42),
		})
		round(tab, 5)
		local marker = create("Frame", tab, {
			BackgroundColor3 = colour.accent, BorderSizePixel = 0,
			Position = UDim2.fromOffset(0, 11), Size = UDim2.fromOffset(2, 20),
		})
		local glyph = icon(tab, index == 1 and images.main or images.settings,
			9, 12, 17, colour.muted)
		local caption = label(tab, name, 29, 0, 58, 42, 12, colour.muted, true)
		local page = create("Frame", window, {
			Name = name .. "Page", BackgroundTransparency = 1,
			Position = UDim2.fromOffset(119, 80), Size = UDim2.fromOffset(243, 342),
			Visible = index == 1,
		})
		tabs[index] = { button = tab, marker = marker, glyph = glyph, caption = caption }
		pages[index] = page
	end

	local overlay = create("Frame", window, {
		Name = "DeviceOptions", BackgroundColor3 = colour.inner,
		BorderSizePixel = 0, Position = UDim2.fromOffset(122, 116),
		Size = UDim2.fromOffset(238, 160), Visible = false, ZIndex = 30,
	})
	round(overlay, 6)
	create("UIStroke", overlay, {
		Color = colour.border, Thickness = 1,
		BorderStrokePosition = Enum.BorderStrokePosition.Inner,
	})

	local function closeOptions()
		popupOpen = false
		overlay.Visible = false
	end


	local function drawSwitch(control, immediate)
		local enabled = control.preview
		if enabled == nil then
			enabled = control.read()
		end
		local held = activePress and activePress.control == control
		local width = held and 23 or 18
		local x = enabled and 48 - 3 - width or 3
		if control.motion then control.motion:Cancel() end
		if control.trackMotion then control.trackMotion:Cancel() end
		local destination = {
			Position = UDim2.fromOffset(x, 4), Size = UDim2.fromOffset(width, 18),
		}
		local fill = enabled and colour.active or colour.raised
		if immediate then
			control.thumb.Position = destination.Position
			control.thumb.Size = destination.Size
			control.track.BackgroundColor3 = fill
		else
			control.motion = TweenService:Create(control.thumb, TweenInfo.new(0.14,
				Enum.EasingStyle.Quart, Enum.EasingDirection.Out), destination)
			control.trackMotion = TweenService:Create(control.track, TweenInfo.new(0.14,
				Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { BackgroundColor3 = fill })
			control.motion:Play()
			control.trackMotion:Play()
		end
	end

	local function showTab(index)
		closeOptions()
		local pressed = activePress
		activePress = nil
		if pressed then
			pressed.control.preview = nil
			drawSwitch(pressed.control, false)
		end
		for i, tab in tabs do
			local selected = index == i
			tab.button.BackgroundColor3 = selected and colour.inner or colour.base
			tab.marker.Visible = selected
			tab.glyph.ImageColor3 = selected and colour.accent or colour.muted
			tab.caption.TextColor3 = selected and colour.text or colour.muted
			pages[i].Visible = selected
		end
	end
	for index, tab in tabs do
		connect(tab.button.Activated, function()
			showTab(index)
		end)
	end
	showTab(1)

	local function toggle(control, value)
		if not state.active then return end
		control.preview = nil
		control.write(value)
		for _, item in controls do drawSwitch(item, false) end
	end

	local function makeSwitch(y, heading, description, read, write, page)
		page = page or pages[1]
		label(page, heading, 4, y, 176, 24, 13, colour.text, true)
		label(page, description, 4, y + 24, 177, 18, 11, colour.muted)
		local track = create("Frame", page, {
			BackgroundColor3 = colour.raised, BorderSizePixel = 0,
			Position = UDim2.fromOffset(190, y + 9), Size = UDim2.fromOffset(48, 26),
		})
		round(track, 13)
		local thumb = create("Frame", track, {
			BackgroundColor3 = colour.text, BorderSizePixel = 0,
			Position = UDim2.fromOffset(3, 4), Size = UDim2.fromOffset(18, 18),
		})
		round(thumb, 9)
		local button = create("TextButton", page, {
			Name = heading .. "Toggle", Text = "", AutoButtonColor = false,
			BackgroundTransparency = 1, Active = true, ZIndex = 4,
			Position = UDim2.fromOffset(0, y), Size = UDim2.fromOffset(243, 47),
		})
		local control = {
			read = read, write = write, thumb = thumb, track = track, button = button,
			motion = nil :: Tween?, trackMotion = nil :: Tween?, preview = nil :: boolean?,
		}
		table.insert(controls, control)
		connect(button.InputBegan, function(input)
			if activePress or not state.active then return end
			local kind = input.UserInputType
			if kind ~= Enum.UserInputType.MouseButton1 and kind ~= Enum.UserInputType.Touch then return end
			activePress = { control = control, input = input, startX = input.Position.X }
			drawSwitch(control, false)
		end)
		connect(button.Activated, function(input)
			if input and (input.UserInputType == Enum.UserInputType.MouseButton1
				or input.UserInputType == Enum.UserInputType.Touch) then
				return
			end
			toggle(control, not read())
		end)
		drawSwitch(control, true)
	end

	label(pages[1], "ASSISTANCE", 4, 0, 200, 24, 10, colour.muted, true)
	makeSwitch(31, "Silent Aim", "Assisted targeting", function()
		return state.enabled
	end, function(enabled)
		state.enabled = enabled
		state.selectedEntity = nil
		notify("Silent Aim", enabled and "Enabled" or "Disabled", 4)
	end)
	create("Frame", pages[1], {
		Position = UDim2.fromOffset(4, 87), Size = UDim2.fromOffset(236, 1),
		BackgroundColor3 = colour.raised, BorderSizePixel = 0,
	})
	makeSwitch(97, "Triggerbot", "Automatic firing", function()
		return state.triggerbot
	end, function(enabled)
		setTriggerbot(enabled)
		notify("Triggerbot", enabled and "Enabled" or "Disabled", 4)
	end)

	label(pages[1], "DEVICE LABEL", 4, 161, 200, 21, 10, colour.muted, true)
	makeSwitch(185, "Device report", "Reported platform only", function()
		return deviceReport ~= nil
	end, function(enabled)
		if enabled then
			local ok, reason = pcall(enableDeviceReport)
			if not ok then
				restoreDeviceReport()
				warn("Device report unavailable: " .. tostring(reason))
				notify("Device", "Report unavailable: " .. tostring(reason), 8)
			end
		else
			restoreDeviceReport()
		end
	end)

	local choose = create("TextButton", pages[1], {
		Name = "ReportedDevice", Text = "", BackgroundColor3 = colour.inner,
		BorderSizePixel = 0, AutoButtonColor = false,
		Position = UDim2.fromOffset(3, 238), Size = UDim2.fromOffset(236, 40),
	})
	round(choose, 5)
	local choiceText = label(choose, state.deviceLabel, 12, 0, 215, 40, 12, colour.text, true)
	-- One checked device label: the server receives a single value, never a set.
	local rows = {}
	local function updateChoices()
		choiceText.Text = "Report as: " .. state.deviceLabel
		for name, row in rows do
			local selected = name == state.deviceLabel
			row.tick.Visible = selected
			row.box.BackgroundColor3 = selected and colour.active or colour.base
			row.button.BackgroundColor3 = selected and colour.active or colour.inner
		end
	end
	for index, name in { "Mobile", "Tablet", "Desktop", "Gamepad" } do
		local row = create("TextButton", overlay, {
			Name = name, Text = "", BackgroundColor3 = colour.inner,
			BorderSizePixel = 0, AutoButtonColor = false, ZIndex = 32,
			Position = UDim2.fromOffset(4, 4 + (index - 1) * 38),
			Size = UDim2.fromOffset(230, 38),
		})
		local optionName = label(row, name, 11, 0, 166, 38, 12, colour.text, false)
		optionName.ZIndex = 33
		local checkBox = create("Frame", row, {
			BackgroundColor3 = colour.base, BorderSizePixel = 0,
			Position = UDim2.fromOffset(197, 9), Size = UDim2.fromOffset(20, 20),
			ZIndex = 33,
		})
		round(checkBox, 4)
		create("UIStroke", checkBox, {
			Thickness = 1, Color = colour.border,
			BorderStrokePosition = Enum.BorderStrokePosition.Inner,
		})
		local tick = icon(checkBox, images.check, 2, 2, 16, colour.text, 34)
		rows[name] = { button = row, tick = tick, box = checkBox }
		connect(row.Activated, function()
			state.deviceLabel = name
			if deviceReport then deviceReport.report() end
			updateChoices()
			closeOptions()
		end)
	end
	updateChoices()
	connect(choose.Activated, function()
		popupOpen = not popupOpen
		overlay.Visible = popupOpen
	end)

	local settings = pages[2]
	label(settings, "KEYBINDS", 4, 0, 250, 24, 10, colour.muted, true)
	local keyNotice = label(settings, "Esc cancels. End unloads.", 4, 262, 236, 23, 11, colour.muted)
	local function readKey(field)
		if field == "menuKey" then return state.menuKey end
		if field == "aimKey" then return state.aimKey end
		return state.triggerKey
	end
	local function writeKey(field, key)
		if field == "menuKey" then state.menuKey = key
		elseif field == "aimKey" then state.aimKey = key
		else state.triggerKey = key end
	end
	local function updateKeys()
		for field, button in bindings do
			local key = readKey(field)
			button.Text = capturing == field and "Press key..." or key.Name
			button.BackgroundColor3 = capturing == field and colour.active or colour.inner
		end
	end
	for index, info in {
		{ "menuKey", "Window", "Show or hide panel" },
		{ "aimKey", "Silent Aim", "Toggle targeting" },
		{ "triggerKey", "Triggerbot", "Toggle firing" },
	} do
		local y = 31 + (index - 1) * 57
		label(settings, info[2], 4, y, 144, 24, 13, colour.text, true)
		label(settings, info[3], 4, y + 22, 144, 17, 11, colour.muted)
		local button = create("TextButton", settings, {
			Name = info[1], Text = "", AutoButtonColor = false,
			Font = Enum.Font.GothamMedium, TextSize = 12, TextColor3 = colour.text,
			BackgroundColor3 = colour.inner, BorderSizePixel = 0,
			Position = UDim2.fromOffset(149, y + 4), Size = UDim2.fromOffset(94, 36),
		})
		round(button, 5)
		bindings[info[1]] = button
		connect(button.Activated, function()
			capturing = info[1]
			keyNotice.Text = "Press a key. Escape cancels."
			keyNotice.TextColor3 = colour.muted
			updateKeys()
		end)
	end
	label(settings, "MOUSE", 4, 194, 236, 18, 10, colour.muted, true)
	makeSwitch(214, "Lock Mouse", "Free cursor in panel", function()
		return state.lockMouse
	end, function(enabled)
		state.lockMouse = enabled
		updateMouse()
	end, settings)
	local unload = create("TextButton", settings, {
		Name = "Unload", Text = "", AutoButtonColor = false,
		BackgroundColor3 = colour.inner, BorderSizePixel = 0,
		Position = UDim2.fromOffset(3, 292), Size = UDim2.fromOffset(236, 43),
	})
	round(unload, 5)
	icon(unload, images.power, 13, 12, 19, colour.alert)
	label(unload, "Unload script", 44, 0, 174, 43, 13, colour.text, true)
	connect(unload.Activated, function()
		state.unload()
	end)
	updateKeys()

	local footer = label(window, "", 17, 434, 339, 24, 11, colour.muted)
	local function updateFooter()
		footer.Text = state.menuKey.Name .. "  -  open / close     End  -  unload"
	end
	updateFooter()
	create("Frame", window, {
		Position = UDim2.fromOffset(12, 428), Size = UDim2.fromOffset(352, 1),
		BackgroundColor3 = colour.raised, BorderSizePixel = 0,
	})

	local function cancelPress()
		local pressed = activePress
		activePress = nil
		if pressed then
			pressed.control.preview = nil
			drawSwitch(pressed.control, false)
		end
		dragging = nil
	end
	local reopen = create("TextButton", screen, {
		Name = "Open", Text = "", AutoButtonColor = false,
		BackgroundColor3 = colour.base, BorderSizePixel = 0,
		Position = UDim2.new(0, 14, 0.5, -22), Size = UDim2.fromOffset(48, 44),
		Visible = false,
	})
	round(reopen, 7)
	create("UIStroke", reopen, {
		Color = colour.border, Thickness = 1,
		BorderStrokePosition = Enum.BorderStrokePosition.Inner,
	})
	icon(reopen, images.main, 15, 13, 18, colour.accent)
	local function setVisible(visible)
		state.uiVisible = visible
		window.Visible = visible
		reopen.Visible = not visible
		if not visible then
			closeOptions()
			capturing = nil
			cancelPress()
			updateKeys()
		end
		updateMouse()
	end
	connect(minimise.Activated, function()
		setVisible(false)
	end)
	connect(reopen.Activated, function()
		setVisible(true)
	end)
	state.uiSync = function()
		for _, control in controls do drawSwitch(control, false) end
	end
	state.uiDestroy = function()
		setVisible(false)
		releaseMouse()
		for _, connection in uiConnections do connection:Disconnect() end
		for _, control in controls do
			if control.motion then control.motion:Cancel() end
			if control.trackMotion then control.trackMotion:Cancel() end
		end
		state.uiSync = nil
		state.uiDestroy = nil
		screen:Destroy()
	end

	connect(UserInputService.InputBegan, function(input, processed)
		if popupOpen and (input.UserInputType == Enum.UserInputType.MouseButton1
			or input.UserInputType == Enum.UserInputType.Touch) then
			local position = Vector2.new(input.Position.X, input.Position.Y)
			local function contains(object)
				local p, size = object.AbsolutePosition, object.AbsoluteSize
				return position.X >= p.X and position.X <= p.X + size.X
					and position.Y >= p.Y and position.Y <= p.Y + size.Y
			end
			if not contains(overlay) and not contains(choose) then closeOptions() end
		end
		if input.UserInputType ~= Enum.UserInputType.Keyboard then return end
		if popupOpen and input.KeyCode.Name == "Escape" then
			closeOptions()
			return
		end
		if capturing then
			local key = input.KeyCode
			if key.Name == "Escape" then
				capturing = nil
				keyNotice.Text = "Esc cancels. End unloads."
				keyNotice.TextColor3 = colour.muted
			elseif key.Name == "End" or key.Name == "Unknown" then
				keyNotice.Text = "That key is reserved."
				keyNotice.TextColor3 = colour.alert
			else
				local conflict = false
				for _, field in { "menuKey", "aimKey", "triggerKey" } do
					if field ~= capturing and readKey(field).Name == key.Name then
						conflict = true
						break
					end
				end
				if conflict then
					keyNotice.Text = "That key is already assigned."
					keyNotice.TextColor3 = colour.alert
				else
					writeKey(capturing, key)
					capturing = nil
					keyNotice.Text = "Esc cancels. End unloads."
					keyNotice.TextColor3 = colour.muted
					updateFooter()
				end
			end
			updateKeys()
			return
		end
		if processed or UserInputService:GetFocusedTextBox() then return end
		if input.KeyCode.Name == state.menuKey.Name then
			setVisible(not state.uiVisible)
		elseif input.KeyCode.Name == state.aimKey.Name then
			state.enabled = not state.enabled
			state.selectedEntity = nil
			if state.uiSync then state.uiSync() end
			notify("Silent Aim", state.enabled and "Enabled" or "Disabled", 4)
		elseif input.KeyCode.Name == state.triggerKey.Name then
			setTriggerbot(not state.triggerbot)
			if state.uiSync then state.uiSync() end
			notify("Triggerbot", state.triggerbot and "Enabled" or "Disabled", 4)
		elseif input.KeyCode.Name == "End" then
			state.unload()
		end
	end)

	connect(UserInputService.InputChanged, function(input)
		if activePress then
			local pressed = activePress
			local touch = pressed.input.UserInputType == Enum.UserInputType.Touch
			if (touch and input == pressed.input) or (not touch
				and input.UserInputType == Enum.UserInputType.MouseMovement) then
				local delta = input.Position.X - pressed.startX
				local control = pressed.control
				local preview = nil
				if math.abs(delta) >= 12 then preview = delta > 0 end
				if control.preview ~= preview then
					control.preview = preview
					drawSwitch(control, false)
				end
			end
		end
		if not dragging or not state.uiVisible then return end
		local isTouch = dragging.UserInputType == Enum.UserInputType.Touch
		if (isTouch and input ~= dragging) or (not isTouch
			and input.UserInputType ~= Enum.UserInputType.MouseMovement) then return end
		local camera = workspace.CurrentCamera
		if not camera then return end
		local pointer = Vector2.new(input.Position.X, input.Position.Y)
		local delta = pointer - pointerStart
		local size = window.AbsoluteSize
		local centre = window.AbsolutePosition + size / 2 + delta
		local view = camera.ViewportSize
		window.Position = UDim2.fromOffset(
			math.clamp(centre.X, size.X / 2, math.max(size.X / 2, view.X - size.X / 2)),
			math.clamp(centre.Y, size.Y / 2, math.max(size.Y / 2, view.Y - size.Y / 2))
		)
		pointerStart = pointer
	end)

	connect(UserInputService.InputEnded, function(input)
		if activePress then
			local pressed = activePress
			local touch = pressed.input.UserInputType == Enum.UserInputType.Touch
			if (touch and pressed.input == input) or (not touch
				and input.UserInputType == Enum.UserInputType.MouseButton1) then
				activePress = nil
				local control = pressed.control
				local delta = input.Position.X - pressed.startX
				if math.abs(delta) >= 12 then
					toggle(control, delta > 0)
				else
					local p, size = control.button.AbsolutePosition, control.button.AbsoluteSize
					local x, y = input.Position.X, input.Position.Y
					if x >= p.X and x <= p.X + size.X and y >= p.Y and y <= p.Y + size.Y then
						toggle(control, not control.read())
					else
						control.preview = nil
						drawSwitch(control, false)
					end
				end
			end
		end
		if dragging and (input == dragging or (dragging.UserInputType == Enum.UserInputType.MouseButton1
			and input.UserInputType == Enum.UserInputType.MouseButton1)) then dragging = nil end
	end)

	connect(GuiService.MenuOpened, updateMouse)
	connect(GuiService.MenuClosed, updateMouse)
	connect(UserInputService.WindowFocused, updateMouse)
	connect(UserInputService.WindowFocusReleased, function()
		releaseMouse()
		cancelPress()
		closeOptions()
		capturing = nil
		keyNotice.Text = "Esc cancels. End unloads."
		keyNotice.TextColor3 = colour.muted
		updateKeys()
	end)

	connect(header.InputBegan, function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1
			or input.UserInputType == Enum.UserInputType.Touch then
			dragging = input
			pointerStart = Vector2.new(input.Position.X, input.Position.Y)
		end
	end)
	local camera = workspace.CurrentCamera
	if camera then connect(camera:GetPropertyChangedSignal("ViewportSize"), resize) end
	setVisible(true)
end

function state.unload(silent)
	if not state.active then
		return
	end
	state.active = false
	state.enabled = false
	setTriggerbot(false)
	local destroy = state.uiDestroy
	if destroy then
		destroy()
	end
	for index = #state.connections, 1, -1 do
		state.connections[index]:Disconnect()
		state.connections[index] = nil
	end
	restoreDeviceReport()

	if ClientShootable.Shoot == shootWithTarget then
		ClientShootable.Shoot = originalShoot
	else
		warn("Shoot changed externally; original function was not restored")
	end
	if getupvalue(originalShoot, originIndex) == redirectedOrigin then
		setupvalue(originalShoot, originIndex, originalOrigin)
	else
		warn("Combat origin changed externally; original function was not restored")
	end
	if environment.__aimSession == state then
		environment.__aimSession = nil
	end
	if not silent then
		notify("YS - SNIPER ARENA", "Unloaded", 5)
	end
end

setupvalue(originalShoot, originIndex, redirectedOrigin)
assert(getupvalue(originalShoot, originIndex) == redirectedOrigin,
	"Could not install the combat origin redirect")
ClientShootable.Shoot = shootWithTarget
environment.__aimSession = state

local taken = {}
local function savedKey(field, fallback)
	local candidate = previous and previous[field]
	if typeof(candidate) ~= "EnumItem" or tostring(candidate.EnumType) ~= "Enum.KeyCode"
		or candidate.Name == "Unknown" or candidate.Name == "End"
		or candidate.Name == "Escape" or taken[candidate.Name] then
		candidate = fallback
	end
	-- F6 was the old default, not an intentional custom binding.
	if field == "aimKey" and candidate.Name == "F6" then candidate = Enum.KeyCode.V end
	if taken[candidate.Name] then
		for _, option in { Enum.KeyCode.RightShift, Enum.KeyCode.V, Enum.KeyCode.T, Enum.KeyCode.B } do
			if not taken[option.Name] then
				candidate = option
				break
			end
		end
	end
	taken[candidate.Name] = true
	return candidate
end
state.menuKey = savedKey("menuKey", Enum.KeyCode.RightShift)
state.aimKey = savedKey("aimKey", Enum.KeyCode.V)
state.triggerKey = savedKey("triggerKey", Enum.KeyCode.T)
local priorDevice = previous and previous.deviceLabel
if priorDevice == "Mobile" or priorDevice == "Tablet"
	or priorDevice == "Desktop" or priorDevice == "Gamepad" then
	state.deviceLabel = priorDevice
end
state.uiVisible = true
if previous and type(previous.lockMouse) == "boolean" then
	state.lockMouse = previous.lockMouse
end

setTriggerbot(true)
local reportReady, reportReason = pcall(enableDeviceReport)
if not reportReady then
	restoreDeviceReport()
	warn("Device report unavailable: " .. tostring(reportReason))
end
local interfaceReady, interfaceReason = pcall(buildPanel)
if not interfaceReady then
	state.unload(true)
	warn("Could not build the interface: " .. tostring(interfaceReason))
	notify("Interface", "Could not open: " .. tostring(interfaceReason), 10)
	return
end
notify("YS Controls", state.menuKey.Name:gsub("(%l)(%u)", "%1 %2") .. " - show or hide panel\n"
	.. state.aimKey.Name:gsub("(%l)(%u)", "%1 %2") .. " - toggle Silent Aim\n"
	.. state.triggerKey.Name:gsub("(%l)(%u)", "%1 %2") .. " - toggle Triggerbot\nEnd - unload", 20)

How to Execute Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF

Step 1: Copy Code: Click the Copy Code button in the viewer above to grab the clean Lua loadstring.

Step 2: Launch Executor: Open a compatible, unpatched executor. If you need one, check our Roblox Executors Directory.

Step 3: Join Experience: Launch Roblox and join Sniper Arena.

Step 4: Attach & Run: Attach/inject your executor into the Roblox process, paste the code into the script tab, and press Execute.

Created By

scriptsforgames
scriptsforgames
Script Creator
View Author Profile

Roblox Experience

[🎃Event] Sniper Arena
Sniper Arena
By Roblox
Active Players:0
Play on Roblox

Features & Information

Execute Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF. Key system required, created by scriptsforgames, updated Oct 9, 2026. Tested and working on supported executors.

Script Changelog (2)

@scriptsforgamesOct 16, 2026

TRIGGERBOT + DEVICE SPOOFER AND UI ADDED

@scriptsforgamesOct 9, 2026

Create script

Community Comments (0)

No comments yet for this script.

Frequently Asked Questions

How do I execute Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF in Roblox?

To run Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF, copy the Lua loadstring from the code viewer above, launch Roblox and join Sniper Arena, attach a working executor (such as Potassium, Solara, or Delta from our Executors directory), paste the code into your executor console, and click Execute.

Is Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF keyless or does it require an access key?

Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF requires an access key. You can retrieve the official key directly using the Get Script Key link provided above.

Is Sniper Arena Script – SA - SILENT+TRIGGERBOT+DEVICE SPOOF currently safe and working?

This script is active and operational. Always test scripts using a secondary (alt) Roblox account to safeguard your main profile against anti-cheat bans.