-- Check for table that is shared between executions. if not shared then return warn("No shared, no script.") end -- Detach previous instance. if shared.SilentAim then shared.SilentAim.detach() end local SilentAim = { enabled = true, showFov = true, showHighlight = true, fovRadius = 200, targetPart = "Head", highlightColor = Color3.fromRGB(255, 255, 255), target = nil, espEnabled = true, espBoxes = true, espNames = true, espHealth = true, espChams = true, espNonEnemies = false, espMaxDistance = 1500, teamColors = { Police = Color3.fromRGB(60, 140, 255), Prisoner = Color3.fromRGB(255, 150, 40), Fugitive = Color3.fromRGB(255, 50, 50), }, defaultTeamColor = Color3.fromRGB(220, 220, 220), } -- Constants. local GUN_MODULE_NAME = "GunClient" -- Services. local playersService = game:GetService("Players") local userInputService = game:GetService("UserInputService") local runService = game:GetService("RunService") local localPlayer = playersService.LocalPlayer local currentCamera = workspace.CurrentCamera -- State. local connections = {} local espObjects = {} local espFailed = {} local espErrorLogged = false local alive = true local oldIndex = nil local currentPart = nil local rayfield = nil local hiddenUi = gethui() local fovCircle = Drawing.new("Circle") local targetHighlight = Instance.new("Highlight") fovCircle.NumSides = 64 fovCircle.Thickness = 1 fovCircle.Color = Color3.fromRGB(255, 255, 255) fovCircle.Transparency = 1 targetHighlight.FillTransparency = 0.5 targetHighlight.OutlineTransparency = 0 targetHighlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop targetHighlight.Enabled = false targetHighlight.Parent = hiddenUi ---Mirror the game's damage rules. Never call game code, it strips our capabilities. ---@param attackerTeam Team? ---@param victimTeam Team? ---@return boolean local function canDamageTeam(attackerTeam, victimTeam) local attackerName = attackerTeam and attackerTeam.Name local victimName = victimTeam and victimTeam.Name if attackerName == "NoTeam" or victimName == "NoTeam" then return false end if attackerName == "Police" then return victimName ~= "Police" end if attackerName == "Prisoner" or attackerName == "Fugitive" then return victimName == "Police" end return true end ---Get the color for a player's team. ---@param player Player ---@return Color3 local function getTeamColor(player) local team = player.Team if not team then return SilentAim.defaultTeamColor end return SilentAim.teamColors[team.Name] or team.TeamColor.Color end ---Find the closest damageable enemy part to the cursor inside the FOV. ---@return BasePart? local function getTargetPart() local closestPart, closestDistance = nil, SilentAim.fovRadius local mousePosition = userInputService:GetMouseLocation() local localTeam = localPlayer.Team for _, player in ipairs(playersService:GetPlayers()) do if player == localPlayer then continue end if not canDamageTeam(localTeam, player.Team) then continue end local character = player.Character if not character then continue end local humanoid = character:FindFirstChildOfClass("Humanoid") local part = character:FindFirstChild(SilentAim.targetPart) if not (humanoid and part and humanoid.Health > 0) then continue end local screenPosition, onScreen = currentCamera:WorldToViewportPoint(part.Position) if not onScreen then continue end local distance = (Vector2.new(screenPosition.X, screenPosition.Y) - mousePosition).Magnitude if distance < closestDistance then closestDistance = distance closestPart = part end end return closestPart end ---Create the chams and drawings for a player. Chams first so a parent failure leaks nothing. ---@param player Player local function createEsp(player) local chams = Instance.new("Highlight") chams.FillTransparency = 0.75 chams.OutlineTransparency = 0.3 chams.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop chams.Enabled = false chams.Parent = hiddenUi local box = Drawing.new("Square") box.Thickness = 1 box.Filled = false box.Transparency = 1 local name = Drawing.new("Text") name.Size = 13 name.Center = true name.Outline = true name.Transparency = 1 local healthBar = Drawing.new("Line") healthBar.Thickness = 2 healthBar.Transparency = 1 espObjects[player] = { box = box, name = name, healthBar = healthBar, chams = chams } end ---Hide every ESP element for a player. ---@param esp table local function hideEsp(esp) esp.box.Visible = false esp.name.Visible = false esp.healthBar.Visible = false esp.chams.Enabled = false esp.chams.Adornee = nil end ---Destroy a player's ESP. ---@param player Player local function destroyEsp(player) espFailed[player] = nil local esp = espObjects[player] if not esp then return end espObjects[player] = nil esp.box:Remove() esp.name:Remove() esp.healthBar:Remove() esp.chams:Destroy() end ---Update a player's ESP for this frame. ---@param player Player ---@param esp table local function updateEsp(player, esp) if not SilentAim.espEnabled then return hideEsp(esp) end local character = player.Character local humanoid = character and character:FindFirstChildOfClass("Humanoid") local root = character and character:FindFirstChild("HumanoidRootPart") if not (humanoid and root and humanoid.Health > 0) then return hideEsp(esp) end if not SilentAim.espNonEnemies and not canDamageTeam(localPlayer.Team, player.Team) then return hideEsp(esp) end local distance = (currentCamera.CFrame.Position - root.Position).Magnitude if distance > SilentAim.espMaxDistance then return hideEsp(esp) end local rootScreen, onScreen = currentCamera:WorldToViewportPoint(root.Position) if not onScreen then return hideEsp(esp) end local color = getTeamColor(player) local topScreen = currentCamera:WorldToViewportPoint(root.Position + Vector3.new(0, 3, 0)) local bottomScreen = currentCamera:WorldToViewportPoint(root.Position - Vector3.new(0, 3.5, 0)) local height = math.abs(topScreen.Y - bottomScreen.Y) local width = height / 1.8 local left = rootScreen.X - width / 2 esp.box.Visible = SilentAim.espBoxes esp.box.Color = color esp.box.Size = Vector2.new(width, height) esp.box.Position = Vector2.new(left, topScreen.Y) esp.name.Visible = SilentAim.espNames esp.name.Color = color esp.name.Text = string.format("%s [%dm]", player.Name, math.floor(distance)) esp.name.Position = Vector2.new(rootScreen.X, topScreen.Y - 16) local healthRatio = math.clamp(humanoid.Health / math.max(humanoid.MaxHealth, 1), 0, 1) esp.healthBar.Visible = SilentAim.espHealth esp.healthBar.Color = Color3.fromRGB(255, 0, 0):Lerp(Color3.fromRGB(0, 255, 0), healthRatio) esp.healthBar.From = Vector2.new(left - 4, topScreen.Y + height) esp.healthBar.To = Vector2.new(left - 4, topScreen.Y + height - height * healthRatio) esp.chams.Enabled = SilentAim.espChams esp.chams.Adornee = character esp.chams.FillColor = color esp.chams.OutlineColor = color end ---Detach the hooks, drawings and menu. function SilentAim.detach() alive = false if oldIndex then hookmetamethod(game, "__index", oldIndex) oldIndex = nil end for _, connection in ipairs(connections) do connection:Disconnect() end for player in pairs(espObjects) do destroyEsp(player) end fovCircle:Remove() targetHighlight:Destroy() if rayfield then rayfield:Destroy() end shared.SilentAim = nil end ---Build the Rayfield menu. local function createMenu() local response = request({ Url = "https://sirius.menu/rayfield", Method = "GET" }) rayfield = loadstring(response.Body)() local window = rayfield:CreateWindow({ Name = "Riot City", LoadingTitle = "Silent Aim + ESP", LoadingSubtitle = "Riot City", ConfigurationSaving = { Enabled = false }, KeySystem = false, }) local aimTab = window:CreateTab("Aim", 4483362458) aimTab:CreateToggle({ Name = "Silent Aim", CurrentValue = SilentAim.enabled, Callback = function(value) SilentAim.enabled = value end, }) aimTab:CreateKeybind({ Name = "Toggle Keybind", CurrentKeybind = "P", HoldToInteract = false, Callback = function() SilentAim.enabled = not SilentAim.enabled end, }) aimTab:CreateDropdown({ Name = "Target Part", Options = { "Head", "HumanoidRootPart", "UpperTorso", "Torso" }, CurrentOption = { SilentAim.targetPart }, MultipleOptions = false, Callback = function(options) SilentAim.targetPart = options[1] end, }) aimTab:CreateSlider({ Name = "FOV Radius", Range = { 50, 800 }, Increment = 10, CurrentValue = SilentAim.fovRadius, Callback = function(value) SilentAim.fovRadius = value end, }) aimTab:CreateToggle({ Name = "Show FOV Circle", CurrentValue = SilentAim.showFov, Callback = function(value) SilentAim.showFov = value end, }) aimTab:CreateToggle({ Name = "Highlight Target", CurrentValue = SilentAim.showHighlight, Callback = function(value) SilentAim.showHighlight = value end, }) aimTab:CreateColorPicker({ Name = "Target Highlight Color", Color = SilentAim.highlightColor, Callback = function(value) SilentAim.highlightColor = value end, }) local espTab = window:CreateTab("ESP", 4483362458) espTab:CreateToggle({ Name = "ESP", CurrentValue = SilentAim.espEnabled, Callback = function(value) SilentAim.espEnabled = value end, }) espTab:CreateToggle({ Name = "Boxes", CurrentValue = SilentAim.espBoxes, Callback = function(value) SilentAim.espBoxes = value end, }) espTab:CreateToggle({ Name = "Names + Distance", CurrentValue = SilentAim.espNames, Callback = function(value) SilentAim.espNames = value end, }) espTab:CreateToggle({ Name = "Health Bar", CurrentValue = SilentAim.espHealth, Callback = function(value) SilentAim.espHealth = value end, }) espTab:CreateToggle({ Name = "Chams", CurrentValue = SilentAim.espChams, Callback = function(value) SilentAim.espChams = value end, }) espTab:CreateToggle({ Name = "Show Non-Enemies", CurrentValue = SilentAim.espNonEnemies, Callback = function(value) SilentAim.espNonEnemies = value end, }) espTab:CreateSlider({ Name = "Max Distance", Range = { 100, 3000 }, Increment = 50, CurrentValue = SilentAim.espMaxDistance, Callback = function(value) SilentAim.espMaxDistance = value end, }) local colorsTab = window:CreateTab("Team Colors", 4483362458) for _, teamName in ipairs({ "Police", "Prisoner", "Fugitive" }) do colorsTab:CreateColorPicker({ Name = teamName, Color = SilentAim.teamColors[teamName], Callback = function(value) SilentAim.teamColors[teamName] = value end, }) end end ---Hook Mouse.Hit reads coming from the gun module and run the ESP. local function init() oldIndex = hookmetamethod(game, "__index", newcclosure(function(self, key) if key ~= "Hit" or checkcaller() or not SilentAim.enabled or not currentPart then return oldIndex(self, key) end -- Only the gun module should see the spoofed value. local callingScript = getcallingscript() if not callingScript or callingScript.Name ~= GUN_MODULE_NAME then return oldIndex(self, key) end return CFrame.new(currentPart.Position) end)) table.insert(connections, playersService.PlayerRemoving:Connect(destroyEsp)) -- Create objects off the render thread, failures are logged once per player. task.spawn(function() while alive do for _, player in ipairs(playersService:GetPlayers()) do if player == localPlayer or espObjects[player] or espFailed[player] then continue end local success, err = pcall(createEsp, player) if not success then espFailed[player] = true warn("ESP create failed:", player.Name, err) end end task.wait(0.25) end end) table.insert(connections, runService.RenderStepped:Connect(function() fovCircle.Radius = SilentAim.fovRadius fovCircle.Position = userInputService:GetMouseLocation() fovCircle.Visible = SilentAim.enabled and SilentAim.showFov currentPart = SilentAim.enabled and getTargetPart() or nil SilentAim.target = currentPart if currentPart and SilentAim.showHighlight then targetHighlight.Adornee = currentPart.Parent targetHighlight.FillColor = SilentAim.highlightColor targetHighlight.OutlineColor = SilentAim.highlightColor targetHighlight.Enabled = true else targetHighlight.Enabled = false targetHighlight.Adornee = nil end for player, esp in pairs(espObjects) do local success, err = pcall(updateEsp, player, esp) if not success and not espErrorLogged then espErrorLogged = true warn("ESP update failed:", err) end end end)) end ---Handle init errors. ---@param error string local function onInitError(error) warn("Failed to init.") warn(error) warn(debug.traceback()) SilentAim.detach() end shared.SilentAim = SilentAim xpcall(init, onInitError) xpcall(createMenu, function(error) warn("Menu failed:", error) end)