-- init
if not game:IsLoaded() then
game.Loaded:Wait()
end
if not syn or not protectgui then
getgenv().protectgui = function() end
end
--[[
Universal Silent Aim -> adapted for "Project Remix [Gun Game]" (place 15073271237)
Executor target: Volt (docs.voltbz.net)
Why this differs from the generic Universal Silent Aim:
* Project Remix guns are HITSCAN via the game's own DamageService:Bulletcast /
:PierceBulletcast (main-thread), NOT workspace:Raycast / FindPartOnRay / Mouse.Hit.
* Projectile weapons (rockets / thrown / katana) fire via ProjectileService.NewProjectile.
* Hit registration is CLIENT-AUTHORITATIVE: the weapon resolves the hit part with
DamageService:GetHitTarget and applies damage with DamageService:Damage itself,
so bending the cast direction (or projectile velocity) toward a target lands the hit.
* The generic build hooked game.__namecall / Mouse.__index, which never intercept the
game's custom cast methods (and the bullet SIMULATION runs inside a parallel Actor VM
that main-thread hooks can't reach) -- so it did nothing here. This build hooks the
real chokepoints instead.
]]
local SilentAimSettings = {
Enabled = false,
ClassName = "Project Remix Silent Aim - Averiias, Stefanuk12, xaxa (Bulletcast port)",
ToggleKey = "RightAlt",
TeamCheck = false,
VisibleCheck = false,
Wallbang = false,
TargetPart = "HumanoidRootPart",
FOVRadius = 130,
FOVVisible = false,
ShowSilentAimTarget = false,
ProjectilePrediction = false,
ProjectilePredictionAmount = 0.165,
HitChance = 100
}
-- variables
getgenv().SilentAimSettings = SilentAimSettings
local MainFileName = "UniversalSilentAim"
local FileToSave = ""
local Camera = workspace.CurrentCamera
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local HttpService = game:GetService("HttpService")
local LocalPlayer = Players.LocalPlayer
local GetPlayers = Players.GetPlayers
local WorldToViewportPoint = Camera.WorldToViewportPoint
local GetPartsObscuringTarget = Camera.GetPartsObscuringTarget
local FindFirstChild = game.FindFirstChild
local RenderStepped = RunService.RenderStepped
local GetMouseLocation = UserInputService.GetMouseLocation
local resume = coroutine.resume
local create = coroutine.create
local ValidTargetParts = {"Head", "HumanoidRootPart"}
local PredictionAmount = 0.165
local mouse_box = Drawing.new("Square")
mouse_box.Visible = false
mouse_box.ZIndex = 999
mouse_box.Color = Color3.fromRGB(54, 57, 241)
mouse_box.Thickness = 20
mouse_box.Size = Vector2.new(20, 20)
mouse_box.Filled = true
local fov_circle = Drawing.new("Circle")
fov_circle.Thickness = 1
fov_circle.NumSides = 100
fov_circle.Radius = 180
fov_circle.Filled = false
fov_circle.Visible = false
fov_circle.ZIndex = 999
fov_circle.Transparency = 1
fov_circle.Color = Color3.fromRGB(54, 57, 241)
-- resolve the game's framework services (Volt: getrenv exposes the game's real _G)
local GameGlobal = getrenv()._G
local DamageService, ProjectileService
do
local ok = pcall(function()
DamageService = GameGlobal:GetService("DamageService")
ProjectileService = GameGlobal:GetService("ProjectileService")
end)
if not ok or not DamageService then
warn("[SilentAim] Could not resolve DamageService/ProjectileService -- game framework changed?")
end
end
function CalculateChance(Percentage)
-- // Floor the percentage
Percentage = math.floor(Percentage)
-- // Get the chance
local chance = math.floor(Random.new():NextNumber(0, 1) * 100) / 100
-- // Return
return chance <= Percentage / 100
end
--[[file handling]] do
if not isfolder(MainFileName) then
makefolder(MainFileName)
end
if not isfolder(string.format("%s/%s", MainFileName, tostring(game.PlaceId))) then
makefolder(string.format("%s/%s", MainFileName, tostring(game.PlaceId)))
end
end
-- functions
local function GetFiles() -- credits to the linoria lib for this function, listfiles returns the files full path and its annoying
local out = {}
local Files = listfiles(string.format("%s/%s", MainFileName, tostring(game.PlaceId)))
for i = 1, #Files do
local file = Files[i]
if file:sub(-4) == '.lua' then
local pos = file:find('.lua', 1, true)
local start = pos
local char = file:sub(pos, pos)
while char ~= '/' and char ~= '\\' and char ~= '' do
pos = pos - 1
char = file:sub(pos, pos)
end
if char == '/' or char == '\\' then
table.insert(out, file:sub(pos + 1, start - 1))
end
end
end
return out
end
local function UpdateFile(FileName)
assert(FileName and FileName ~= "", "oopsies")
writefile(string.format("%s/%s/%s.lua", MainFileName, tostring(game.PlaceId), FileName), HttpService:JSONEncode(SilentAimSettings))
end
local function LoadFile(FileName)
assert(FileName and FileName ~= "", "oopsies")
local File = string.format("%s/%s/%s.lua", MainFileName, tostring(game.PlaceId), FileName)
local ConfigData = HttpService:JSONDecode(readfile(File))
for Index, Value in next, ConfigData do
SilentAimSettings[Index] = Value
end
end
local function getPositionOnScreen(Vector)
-- WorldToViewportPoint matches UserInputService:GetMouseLocation (both include the GUI inset)
local Vec3, OnScreen = WorldToViewportPoint(Camera, Vector)
return Vector2.new(Vec3.X, Vec3.Y), OnScreen
end
local function getMousePosition()
return GetMouseLocation(UserInputService)
end
-- Project Remix characters live in workspace.Characters. The authoritative root is a
-- top-level HumanoidRootPart (CollisionGroup "PlayerRoot"); the visible/hittable R15 limbs
-- (CollisionGroup "Hitbox") sit under a "Playermodel" submodel, with the head as "HeadHitbox".
local function isDead(Character)
local health = Character:GetAttribute("Health")
if health ~= nil then
return health <= 0
end
local humanoid = Character:FindFirstChildOfClass("Humanoid")
if humanoid then
return humanoid.Health <= 0
end
return false
end
local function resolvePart(Character, partName)
if partName == "Head" then
local playermodel = FindFirstChild(Character, "Playermodel")
if playermodel then
return FindFirstChild(playermodel, "HeadHitbox")
or FindFirstChild(playermodel, "Head")
or FindFirstChild(playermodel, "UpperTorso")
or FindFirstChild(Character, "HumanoidRootPart")
end
return FindFirstChild(Character, "HumanoidRootPart")
end
-- default / HumanoidRootPart
return FindFirstChild(Character, "HumanoidRootPart")
or (FindFirstChild(Character, "Playermodel") and FindFirstChild(FindFirstChild(Character, "Playermodel"), "UpperTorso"))
end
local function getAimPart(Character)
local target = Options and Options.TargetPart.Value or SilentAimSettings.TargetPart
if target == "Random" then
target = ValidTargetParts[math.random(1, #ValidTargetParts)]
end
return resolvePart(Character, target)
end
-- Project Remix does NOT use Roblox's native Player.Team (always nil). Teams are a player
-- attribute "Team" (integer), only meaningful when workspace attribute "TeamsEnabled" is true
-- (FFA modes leave it false, so every player is a valid target regardless of Team).
local function isSameTeam(Player)
if not workspace:GetAttribute("TeamsEnabled") then return false end
local myTeam = LocalPlayer:GetAttribute("Team")
local theirTeam = Player:GetAttribute("Team")
return myTeam ~= nil and theirTeam ~= nil and myTeam == theirTeam
end
local function IsCharacterVisible(Character, Root)
local LocalCharacter = LocalPlayer.Character
if not LocalCharacter then return true end
local CastPoints = {Root.Position, LocalCharacter, Character}
local IgnoreList = {LocalCharacter, Character}
local Obscuring = #GetPartsObscuringTarget(Camera, CastPoints, IgnoreList)
return Obscuring == 0
end
-- returns the BasePart to aim at (respecting FOV / team / visible / health checks)
local function getTarget()
local mousePosition = getMousePosition()
local radius = (Options and Options.Radius.Value) or SilentAimSettings.FOVRadius or 2000
local closestPart
local closestCharacter
local closestDistance
for _, Player in next, GetPlayers(Players) do
if Player == LocalPlayer then continue end
if Options and Toggles.TeamCheck.Value and isSameTeam(Player) then continue end
local Character = Player.Character
if not Character then continue end
if isDead(Character) then continue end
local Root = FindFirstChild(Character, "HumanoidRootPart")
if not Root then continue end
-- Wallbang bypasses the line-of-sight requirement (the cast is redirected to ignore geometry)
if Options and Toggles.VisibleCheck.Value and not (Toggles.Wallbang and Toggles.Wallbang.Value)
and not IsCharacterVisible(Character, Root) then continue end
local ScreenPosition, OnScreen = getPositionOnScreen(Root.Position)
if not OnScreen then continue end
local Distance = (mousePosition - ScreenPosition).Magnitude
if Distance <= radius and (not closestDistance or Distance < closestDistance) then
local aimPart = getAimPart(Character)
if aimPart then
closestDistance = Distance
closestPart = aimPart
closestCharacter = Character
end
end
end
return closestPart, closestCharacter
end
-- ui creating & handling
local Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/violin-suzutsuki/LinoriaLib/main/Library.lua"))()
Library:SetWatermark("github.com/Averiias")
local Window = Library:CreateWindow({Title = 'Project Remix Silent Aim', Center = true, AutoShow = true, TabPadding = 8, MenuFadeTime = 0.2})
local GeneralTab = Window:AddTab("General")
local MainBOX = GeneralTab:AddLeftTabbox("Main") do
local Main = MainBOX:AddTab("Main")
Main:AddToggle("aim_Enabled", {Text = "Enabled"}):AddKeyPicker("aim_Enabled_KeyPicker", {Default = "RightAlt", SyncToggleState = true, Mode = "Toggle", Text = "Enabled", NoUI = false})
Options.aim_Enabled_KeyPicker:OnClick(function()
SilentAimSettings.Enabled = not SilentAimSettings.Enabled
Toggles.aim_Enabled.Value = SilentAimSettings.Enabled
Toggles.aim_Enabled:SetValue(SilentAimSettings.Enabled)
mouse_box.Visible = SilentAimSettings.Enabled and Toggles.MousePosition.Value
end)
Main:AddToggle("TeamCheck", {Text = "Team Check", Default = SilentAimSettings.TeamCheck}):OnChanged(function()
SilentAimSettings.TeamCheck = Toggles.TeamCheck.Value
end)
Main:AddToggle("VisibleCheck", {Text = "Visible Check", Default = SilentAimSettings.VisibleCheck}):OnChanged(function()
SilentAimSettings.VisibleCheck = Toggles.VisibleCheck.Value
end)
Main:AddToggle("Wallbang", {Text = "Wallbang", Tooltip = "Redirects the shot to ignore geometry so it hits the target through walls (hitscan guns).", Default = SilentAimSettings.Wallbang}):OnChanged(function()
SilentAimSettings.Wallbang = Toggles.Wallbang.Value
end)
Main:AddDropdown("TargetPart", {AllowNull = true, Text = "Target Part", Default = SilentAimSettings.TargetPart, Values = {"Head", "HumanoidRootPart", "Random"}}):OnChanged(function()
SilentAimSettings.TargetPart = Options.TargetPart.Value
end)
Main:AddSlider('HitChance', {
Text = 'Hit chance',
Default = 100,
Min = 0,
Max = 100,
Rounding = 1,
Compact = false,
})
Options.HitChance:OnChanged(function()
SilentAimSettings.HitChance = Options.HitChance.Value
end)
end
local MiscellaneousBOX = GeneralTab:AddLeftTabbox("Miscellaneous")
local FieldOfViewBOX = GeneralTab:AddLeftTabbox("Field Of View") do
local Main = FieldOfViewBOX:AddTab("Visuals")
Main:AddToggle("Visible", {Text = "Show FOV Circle"}):AddColorPicker("Color", {Default = Color3.fromRGB(54, 57, 241)}):OnChanged(function()
fov_circle.Visible = Toggles.Visible.Value
SilentAimSettings.FOVVisible = Toggles.Visible.Value
end)
Main:AddSlider("Radius", {Text = "FOV Circle Radius", Min = 0, Max = 360, Default = 130, Rounding = 0}):OnChanged(function()
fov_circle.Radius = Options.Radius.Value
SilentAimSettings.FOVRadius = Options.Radius.Value
end)
Main:AddToggle("MousePosition", {Text = "Show Silent Aim Target"}):AddColorPicker("MouseVisualizeColor", {Default = Color3.fromRGB(54, 57, 241)}):OnChanged(function()
mouse_box.Visible = Toggles.MousePosition.Value and Toggles.aim_Enabled.Value
mouse_box.Color = Options.MouseVisualizeColor.Value
SilentAimSettings.ShowSilentAimTarget = Toggles.MousePosition.Value
end)
local PredictionTab = MiscellaneousBOX:AddTab("Prediction")
PredictionTab:AddToggle("Prediction", {Text = "Projectile Lead Prediction", Tooltip = "Only affects projectile weapons (rockets / thrown). Hitscan guns are instant and need no lead."}):OnChanged(function()
SilentAimSettings.ProjectilePrediction = Toggles.Prediction.Value
end)
PredictionTab:AddSlider("Amount", {Text = "Prediction Amount", Min = 0.165, Max = 1, Default = 0.165, Rounding = 3}):OnChanged(function()
PredictionAmount = Options.Amount.Value
SilentAimSettings.ProjectilePredictionAmount = Options.Amount.Value
end)
end
local CreateConfigurationBOX = GeneralTab:AddRightTabbox("Create Configuration") do
local Main = CreateConfigurationBOX:AddTab("Create Configuration")
Main:AddInput("CreateConfigTextBox", {Default = "", Numeric = false, Finished = false, Text = "Create Configuration to Create", Tooltip = "Creates a configuration file containing settings you can save and load", Placeholder = "File Name here"}):OnChanged(function()
if Options.CreateConfigTextBox.Value and string.len(Options.CreateConfigTextBox.Value) ~= 0 then
FileToSave = Options.CreateConfigTextBox.Value
end
end)
Main:AddButton("Create Configuration File", function()
if FileToSave ~= "" and FileToSave ~= nil then
UpdateFile(FileToSave)
end
end)
end
local SaveConfigurationBOX = GeneralTab:AddRightTabbox("Save Configuration") do
local Main = SaveConfigurationBOX:AddTab("Save Configuration")
Main:AddDropdown("SaveConfigurationDropdown", {AllowNull = true, Values = GetFiles(), Text = "Choose Configuration to Save"})
Main:AddButton("Save Configuration", function()
if Options.SaveConfigurationDropdown.Value then
UpdateFile(Options.SaveConfigurationDropdown.Value)
end
end)
end
local LoadConfigurationBOX = GeneralTab:AddRightTabbox("Load Configuration") do
local Main = LoadConfigurationBOX:AddTab("Load Configuration")
Main:AddDropdown("LoadConfigurationDropdown", {AllowNull = true, Values = GetFiles(), Text = "Choose Configuration to Load"})
Main:AddButton("Load Configuration", function()
if table.find(GetFiles(), Options.LoadConfigurationDropdown.Value) then
LoadFile(Options.LoadConfigurationDropdown.Value)
Toggles.TeamCheck:SetValue(SilentAimSettings.TeamCheck)
Toggles.VisibleCheck:SetValue(SilentAimSettings.VisibleCheck)
Toggles.Wallbang:SetValue(SilentAimSettings.Wallbang)
Options.TargetPart:SetValue(SilentAimSettings.TargetPart)
Toggles.Visible:SetValue(SilentAimSettings.FOVVisible)
Options.Radius:SetValue(SilentAimSettings.FOVRadius)
Toggles.MousePosition:SetValue(SilentAimSettings.ShowSilentAimTarget)
Toggles.Prediction:SetValue(SilentAimSettings.ProjectilePrediction)
Options.Amount:SetValue(SilentAimSettings.ProjectilePredictionAmount)
Options.HitChance:SetValue(SilentAimSettings.HitChance)
end
end)
end
resume(create(function()
RenderStepped:Connect(function()
if Toggles.MousePosition.Value and Toggles.aim_Enabled.Value then
local part = getTarget()
if part then
local root = (part.Parent and part.Parent:IsA("Model") and part.Parent.PrimaryPart) or part
local ViewportPoint, IsOnScreen = WorldToViewportPoint(Camera, root.Position)
mouse_box.Visible = IsOnScreen
mouse_box.Position = Vector2.new(ViewportPoint.X, ViewportPoint.Y)
else
mouse_box.Visible = false
mouse_box.Position = Vector2.new()
end
end
if Toggles.Visible.Value then
fov_circle.Visible = Toggles.Visible.Value
fov_circle.Color = Options.Color.Value
fov_circle.Position = getMousePosition()
end
end)
end))
-- hooks
-- Guns are hitscan: DamageService:Bulletcast(self, origin, radius, direction, params, name)
-- and :PierceBulletcast(self, origin, radius, direction, params). We bend `direction` toward
-- the target (preserving its magnitude = weapon range). The cast then returns the target's
-- hitbox, the weapon resolves the player with GetHitTarget and applies damage itself.
--
-- Wallbang: bending the direction alone still lets the cast stop on a wall between the muzzle
-- and the target. When Wallbang is on we swap in a RaycastParams that ONLY includes the target
-- character (Include filter), so the ray ignores all geometry and lands on the target's hitbox.
-- Body damage is applied client-side, so this registers through walls.
local function wallbangParams(character)
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = { character }
params.RespectCanCollide = false
params.IgnoreWater = true
return params
end
-- redirects a hitscan cast at the current target; returns (direction, params) to pass through
local function aimCast(origin, direction, params)
if typeof(origin) ~= "Vector3" or typeof(direction) ~= "Vector3" or direction.Magnitude == 0 then
return direction, params
end
local part, character = getTarget()
if not part then return direction, params end
direction = (part.Position - origin).Unit * direction.Magnitude
if Toggles.Wallbang and Toggles.Wallbang.Value and character then
params = wallbangParams(character)
end
return direction, params
end
local shouldAim = function()
return Toggles.aim_Enabled.Value and not checkcaller() and CalculateChance(SilentAimSettings.HitChance)
end
if DamageService then
local oldBulletcast
oldBulletcast = hookfunction(DamageService.Bulletcast, newcclosure(function(self, origin, radius, direction, params, name)
if shouldAim() then
direction, params = aimCast(origin, direction, params)
end
return oldBulletcast(self, origin, radius, direction, params, name)
end))
local oldPierce
oldPierce = hookfunction(DamageService.PierceBulletcast, newcclosure(function(self, origin, radius, direction, params)
if shouldAim() then
direction, params = aimCast(origin, direction, params)
end
return oldPierce(self, origin, radius, direction, params)
end))
end
-- Projectile weapons: ProjectileService.NewProjectile(Player, Type, Position, Velocity, ...)
-- Bend the initial Velocity toward the target (preserving speed). Optional linear lead
-- prediction accounts for projectile travel time.
if ProjectileService then
local oldNewProjectile
oldNewProjectile = hookfunction(ProjectileService.NewProjectile, newcclosure(function(player, projectileType, position, velocity, ...)
if shouldAim() and typeof(position) == "Vector3" and typeof(velocity) == "Vector3" and velocity.Magnitude > 0 then
local part = getTarget()
if part then
local aimPoint = part.Position
if Toggles.Prediction.Value then
local targetVelocity = part.AssemblyLinearVelocity
local speed = velocity.Magnitude
if speed > 0 then
local travelTime = (aimPoint - position).Magnitude / speed
aimPoint = aimPoint + targetVelocity * (travelTime + PredictionAmount)
end
end
velocity = (aimPoint - position).Unit * velocity.Magnitude
end
end
return oldNewProjectile(player, projectileType, position, velocity, ...)
end))
endSilent aim based on Averiias's Universal Silent Aim
No comments yet. Be the first to comment!
1-- init
2if not game:IsLoaded() then
3 game.Loaded:Wait()
4end
5
6if not syn or not protectgui then
7 getgenv().protectgui = function() end
8end
9
10--[[
11 Universal Silent Aim -> adapted for "Project Remix [Gun Game]" (place 15073271237)
12 Executor target: Volt (docs.voltbz.net)
13
14 Why this differs from the generic Universal Silent Aim:
15 * Project Remix guns are HITSCAN via the game's own DamageService:Bulletcast /
16 :PierceBulletcast (main-thread), NOT workspace:Raycast / FindPartOnRay / Mouse.Hit.
17 * Projectile weapons (rockets / thrown / katana) fire via ProjectileService.NewProjectile.
18 * Hit registration is CLIENT-AUTHORITATIVE: the weapon resolves the hit part with
19 DamageService:GetHitTarget and applies damage with DamageService:Damage itself,
20 so bending the cast direction (or projectile velocity) toward a target lands the hit.
21 * The generic build hooked game.__namecall / Mouse.__index, which never intercept the
22 game's custom cast methods (and the bullet SIMULATION runs inside a parallel Actor VM
23 that main-thread hooks can't reach) -- so it did nothing here. This build hooks the
24 real chokepoints instead.
25]]
26
27local SilentAimSettings = {
28 Enabled = false,
29
30 ClassName = "Project Remix Silent Aim - Averiias, Stefanuk12, xaxa (Bulletcast port)",
31 ToggleKey = "RightAlt",
32
33 TeamCheck = false,
34 VisibleCheck = false,
35 Wallbang = false,
36 TargetPart = "HumanoidRootPart",
37
38 FOVRadius = 130,
39 FOVVisible = false,
40 ShowSilentAimTarget = false,
41
42 ProjectilePrediction = false,
43 ProjectilePredictionAmount = 0.165,
44 HitChance = 100
45}
46
47-- variables
48getgenv().SilentAimSettings = SilentAimSettings
49local MainFileName = "UniversalSilentAim"
50local FileToSave = ""
51
52local Camera = workspace.CurrentCamera
53local Players = game:GetService("Players")
54local RunService = game:GetService("RunService")
55local GuiService = game:GetService("GuiService")
56local UserInputService = game:GetService("UserInputService")
57local HttpService = game:GetService("HttpService")
58
59local LocalPlayer = Players.LocalPlayer
60
61local GetPlayers = Players.GetPlayers
62local WorldToViewportPoint = Camera.WorldToViewportPoint
63local GetPartsObscuringTarget = Camera.GetPartsObscuringTarget
64local FindFirstChild = game.FindFirstChild
65local RenderStepped = RunService.RenderStepped
66local GetMouseLocation = UserInputService.GetMouseLocation
67
68local resume = coroutine.resume
69local create = coroutine.create
70
71local ValidTargetParts = {"Head", "HumanoidRootPart"}
72local PredictionAmount = 0.165
73
74local mouse_box = Drawing.new("Square")
75mouse_box.Visible = false
76mouse_box.ZIndex = 999
77mouse_box.Color = Color3.fromRGB(54, 57, 241)
78mouse_box.Thickness = 20
79mouse_box.Size = Vector2.new(20, 20)
80mouse_box.Filled = true
81
82local fov_circle = Drawing.new("Circle")
83fov_circle.Thickness = 1
84fov_circle.NumSides = 100
85fov_circle.Radius = 180
86fov_circle.Filled = false
87fov_circle.Visible = false
88fov_circle.ZIndex = 999
89fov_circle.Transparency = 1
90fov_circle.Color = Color3.fromRGB(54, 57, 241)
91
92-- resolve the game's framework services (Volt: getrenv exposes the game's real _G)
93local GameGlobal = getrenv()._G
94local DamageService, ProjectileService
95do
96 local ok = pcall(function()
97 DamageService = GameGlobal:GetService("DamageService")
98 ProjectileService = GameGlobal:GetService("ProjectileService")
99 end)
100 if not ok or not DamageService then
101 warn("[SilentAim] Could not resolve DamageService/ProjectileService -- game framework changed?")
102 end
103end
104
105function CalculateChance(Percentage)
106 -- // Floor the percentage
107 Percentage = math.floor(Percentage)
108
109 -- // Get the chance
110 local chance = math.floor(Random.new():NextNumber(0, 1) * 100) / 100
111
112 -- // Return
113 return chance <= Percentage / 100
114end
115
116--[[file handling]] do
117 if not isfolder(MainFileName) then
118 makefolder(MainFileName)
119 end
120
121 if not isfolder(string.format("%s/%s", MainFileName, tostring(game.PlaceId))) then
122 makefolder(string.format("%s/%s", MainFileName, tostring(game.PlaceId)))
123 end
124end
125
126-- functions
127local function GetFiles() -- credits to the linoria lib for this function, listfiles returns the files full path and its annoying
128 local out = {}
129 local Files = listfiles(string.format("%s/%s", MainFileName, tostring(game.PlaceId)))
130 for i = 1, #Files do
131 local file = Files[i]
132 if file:sub(-4) == '.lua' then
133 local pos = file:find('.lua', 1, true)
134 local start = pos
135
136 local char = file:sub(pos, pos)
137 while char ~= '/' and char ~= '\\' and char ~= '' do
138 pos = pos - 1
139 char = file:sub(pos, pos)
140 end
141
142 if char == '/' or char == '\\' then
143 table.insert(out, file:sub(pos + 1, start - 1))
144 end
145 end
146 end
147
148 return out
149end
150
151local function UpdateFile(FileName)
152 assert(FileName and FileName ~= "", "oopsies")
153 writefile(string.format("%s/%s/%s.lua", MainFileName, tostring(game.PlaceId), FileName), HttpService:JSONEncode(SilentAimSettings))
154end
155
156local function LoadFile(FileName)
157 assert(FileName and FileName ~= "", "oopsies")
158
159 local File = string.format("%s/%s/%s.lua", MainFileName, tostring(game.PlaceId), FileName)
160 local ConfigData = HttpService:JSONDecode(readfile(File))
161 for Index, Value in next, ConfigData do
162 SilentAimSettings[Index] = Value
163 end
164end
165
166local function getPositionOnScreen(Vector)
167 -- WorldToViewportPoint matches UserInputService:GetMouseLocation (both include the GUI inset)
168 local Vec3, OnScreen = WorldToViewportPoint(Camera, Vector)
169 return Vector2.new(Vec3.X, Vec3.Y), OnScreen
170end
171
172local function getMousePosition()
173 return GetMouseLocation(UserInputService)
174end
175
176-- Project Remix characters live in workspace.Characters. The authoritative root is a
177-- top-level HumanoidRootPart (CollisionGroup "PlayerRoot"); the visible/hittable R15 limbs
178-- (CollisionGroup "Hitbox") sit under a "Playermodel" submodel, with the head as "HeadHitbox".
179local function isDead(Character)
180 local health = Character:GetAttribute("Health")
181 if health ~= nil then
182 return health <= 0
183 end
184 local humanoid = Character:FindFirstChildOfClass("Humanoid")
185 if humanoid then
186 return humanoid.Health <= 0
187 end
188 return false
189end
190
191local function resolvePart(Character, partName)
192 if partName == "Head" then
193 local playermodel = FindFirstChild(Character, "Playermodel")
194 if playermodel then
195 return FindFirstChild(playermodel, "HeadHitbox")
196 or FindFirstChild(playermodel, "Head")
197 or FindFirstChild(playermodel, "UpperTorso")
198 or FindFirstChild(Character, "HumanoidRootPart")
199 end
200 return FindFirstChild(Character, "HumanoidRootPart")
201 end
202 -- default / HumanoidRootPart
203 return FindFirstChild(Character, "HumanoidRootPart")
204 or (FindFirstChild(Character, "Playermodel") and FindFirstChild(FindFirstChild(Character, "Playermodel"), "UpperTorso"))
205end
206
207local function getAimPart(Character)
208 local target = Options and Options.TargetPart.Value or SilentAimSettings.TargetPart
209 if target == "Random" then
210 target = ValidTargetParts[math.random(1, #ValidTargetParts)]
211 end
212 return resolvePart(Character, target)
213end
214
215-- Project Remix does NOT use Roblox's native Player.Team (always nil). Teams are a player
216-- attribute "Team" (integer), only meaningful when workspace attribute "TeamsEnabled" is true
217-- (FFA modes leave it false, so every player is a valid target regardless of Team).
218local function isSameTeam(Player)
219 if not workspace:GetAttribute("TeamsEnabled") then return false end
220 local myTeam = LocalPlayer:GetAttribute("Team")
221 local theirTeam = Player:GetAttribute("Team")
222 return myTeam ~= nil and theirTeam ~= nil and myTeam == theirTeam
223end
224
225local function IsCharacterVisible(Character, Root)
226 local LocalCharacter = LocalPlayer.Character
227 if not LocalCharacter then return true end
228
229 local CastPoints = {Root.Position, LocalCharacter, Character}
230 local IgnoreList = {LocalCharacter, Character}
231 local Obscuring = #GetPartsObscuringTarget(Camera, CastPoints, IgnoreList)
232 return Obscuring == 0
233end
234
235-- returns the BasePart to aim at (respecting FOV / team / visible / health checks)
236local function getTarget()
237 local mousePosition = getMousePosition()
238 local radius = (Options and Options.Radius.Value) or SilentAimSettings.FOVRadius or 2000
239
240 local closestPart
241 local closestCharacter
242 local closestDistance
243
244 for _, Player in next, GetPlayers(Players) do
245 if Player == LocalPlayer then continue end
246 if Options and Toggles.TeamCheck.Value and isSameTeam(Player) then continue end
247
248 local Character = Player.Character
249 if not Character then continue end
250 if isDead(Character) then continue end
251
252 local Root = FindFirstChild(Character, "HumanoidRootPart")
253 if not Root then continue end
254
255 -- Wallbang bypasses the line-of-sight requirement (the cast is redirected to ignore geometry)
256 if Options and Toggles.VisibleCheck.Value and not (Toggles.Wallbang and Toggles.Wallbang.Value)
257 and not IsCharacterVisible(Character, Root) then continue end
258
259 local ScreenPosition, OnScreen = getPositionOnScreen(Root.Position)
260 if not OnScreen then continue end
261
262 local Distance = (mousePosition - ScreenPosition).Magnitude
263 if Distance <= radius and (not closestDistance or Distance < closestDistance) then
264 local aimPart = getAimPart(Character)
265 if aimPart then
266 closestDistance = Distance
267 closestPart = aimPart
268 closestCharacter = Character
269 end
270 end
271 end
272
273 return closestPart, closestCharacter
274end
275
276-- ui creating & handling
277local Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/violin-suzutsuki/LinoriaLib/main/Library.lua"))()
278Library:SetWatermark("github.com/Averiias")
279
280local Window = Library:CreateWindow({Title = 'Project Remix Silent Aim', Center = true, AutoShow = true, TabPadding = 8, MenuFadeTime = 0.2})
281local GeneralTab = Window:AddTab("General")
282local MainBOX = GeneralTab:AddLeftTabbox("Main") do
283 local Main = MainBOX:AddTab("Main")
284
285 Main:AddToggle("aim_Enabled", {Text = "Enabled"}):AddKeyPicker("aim_Enabled_KeyPicker", {Default = "RightAlt", SyncToggleState = true, Mode = "Toggle", Text = "Enabled", NoUI = false})
286 Options.aim_Enabled_KeyPicker:OnClick(function()
287 SilentAimSettings.Enabled = not SilentAimSettings.Enabled
288
289 Toggles.aim_Enabled.Value = SilentAimSettings.Enabled
290 Toggles.aim_Enabled:SetValue(SilentAimSettings.Enabled)
291
292 mouse_box.Visible = SilentAimSettings.Enabled and Toggles.MousePosition.Value
293 end)
294
295 Main:AddToggle("TeamCheck", {Text = "Team Check", Default = SilentAimSettings.TeamCheck}):OnChanged(function()
296 SilentAimSettings.TeamCheck = Toggles.TeamCheck.Value
297 end)
298 Main:AddToggle("VisibleCheck", {Text = "Visible Check", Default = SilentAimSettings.VisibleCheck}):OnChanged(function()
299 SilentAimSettings.VisibleCheck = Toggles.VisibleCheck.Value
300 end)
301 Main:AddToggle("Wallbang", {Text = "Wallbang", Tooltip = "Redirects the shot to ignore geometry so it hits the target through walls (hitscan guns).", Default = SilentAimSettings.Wallbang}):OnChanged(function()
302 SilentAimSettings.Wallbang = Toggles.Wallbang.Value
303 end)
304 Main:AddDropdown("TargetPart", {AllowNull = true, Text = "Target Part", Default = SilentAimSettings.TargetPart, Values = {"Head", "HumanoidRootPart", "Random"}}):OnChanged(function()
305 SilentAimSettings.TargetPart = Options.TargetPart.Value
306 end)
307 Main:AddSlider('HitChance', {
308 Text = 'Hit chance',
309 Default = 100,
310 Min = 0,
311 Max = 100,
312 Rounding = 1,
313
314 Compact = false,
315 })
316 Options.HitChance:OnChanged(function()
317 SilentAimSettings.HitChance = Options.HitChance.Value
318 end)
319end
320
321local MiscellaneousBOX = GeneralTab:AddLeftTabbox("Miscellaneous")
322local FieldOfViewBOX = GeneralTab:AddLeftTabbox("Field Of View") do
323 local Main = FieldOfViewBOX:AddTab("Visuals")
324
325 Main:AddToggle("Visible", {Text = "Show FOV Circle"}):AddColorPicker("Color", {Default = Color3.fromRGB(54, 57, 241)}):OnChanged(function()
326 fov_circle.Visible = Toggles.Visible.Value
327 SilentAimSettings.FOVVisible = Toggles.Visible.Value
328 end)
329 Main:AddSlider("Radius", {Text = "FOV Circle Radius", Min = 0, Max = 360, Default = 130, Rounding = 0}):OnChanged(function()
330 fov_circle.Radius = Options.Radius.Value
331 SilentAimSettings.FOVRadius = Options.Radius.Value
332 end)
333 Main:AddToggle("MousePosition", {Text = "Show Silent Aim Target"}):AddColorPicker("MouseVisualizeColor", {Default = Color3.fromRGB(54, 57, 241)}):OnChanged(function()
334 mouse_box.Visible = Toggles.MousePosition.Value and Toggles.aim_Enabled.Value
335 mouse_box.Color = Options.MouseVisualizeColor.Value
336 SilentAimSettings.ShowSilentAimTarget = Toggles.MousePosition.Value
337 end)
338 local PredictionTab = MiscellaneousBOX:AddTab("Prediction")
339 PredictionTab:AddToggle("Prediction", {Text = "Projectile Lead Prediction", Tooltip = "Only affects projectile weapons (rockets / thrown). Hitscan guns are instant and need no lead."}):OnChanged(function()
340 SilentAimSettings.ProjectilePrediction = Toggles.Prediction.Value
341 end)
342 PredictionTab:AddSlider("Amount", {Text = "Prediction Amount", Min = 0.165, Max = 1, Default = 0.165, Rounding = 3}):OnChanged(function()
343 PredictionAmount = Options.Amount.Value
344 SilentAimSettings.ProjectilePredictionAmount = Options.Amount.Value
345 end)
346end
347
348local CreateConfigurationBOX = GeneralTab:AddRightTabbox("Create Configuration") do
349 local Main = CreateConfigurationBOX:AddTab("Create Configuration")
350
351 Main:AddInput("CreateConfigTextBox", {Default = "", Numeric = false, Finished = false, Text = "Create Configuration to Create", Tooltip = "Creates a configuration file containing settings you can save and load", Placeholder = "File Name here"}):OnChanged(function()
352 if Options.CreateConfigTextBox.Value and string.len(Options.CreateConfigTextBox.Value) ~= 0 then
353 FileToSave = Options.CreateConfigTextBox.Value
354 end
355 end)
356
357 Main:AddButton("Create Configuration File", function()
358 if FileToSave ~= "" and FileToSave ~= nil then
359 UpdateFile(FileToSave)
360 end
361 end)
362end
363
364local SaveConfigurationBOX = GeneralTab:AddRightTabbox("Save Configuration") do
365 local Main = SaveConfigurationBOX:AddTab("Save Configuration")
366 Main:AddDropdown("SaveConfigurationDropdown", {AllowNull = true, Values = GetFiles(), Text = "Choose Configuration to Save"})
367 Main:AddButton("Save Configuration", function()
368 if Options.SaveConfigurationDropdown.Value then
369 UpdateFile(Options.SaveConfigurationDropdown.Value)
370 end
371 end)
372end
373
374local LoadConfigurationBOX = GeneralTab:AddRightTabbox("Load Configuration") do
375 local Main = LoadConfigurationBOX:AddTab("Load Configuration")
376
377 Main:AddDropdown("LoadConfigurationDropdown", {AllowNull = true, Values = GetFiles(), Text = "Choose Configuration to Load"})
378 Main:AddButton("Load Configuration", function()
379 if table.find(GetFiles(), Options.LoadConfigurationDropdown.Value) then
380 LoadFile(Options.LoadConfigurationDropdown.Value)
381
382 Toggles.TeamCheck:SetValue(SilentAimSettings.TeamCheck)
383 Toggles.VisibleCheck:SetValue(SilentAimSettings.VisibleCheck)
384 Toggles.Wallbang:SetValue(SilentAimSettings.Wallbang)
385 Options.TargetPart:SetValue(SilentAimSettings.TargetPart)
386 Toggles.Visible:SetValue(SilentAimSettings.FOVVisible)
387 Options.Radius:SetValue(SilentAimSettings.FOVRadius)
388 Toggles.MousePosition:SetValue(SilentAimSettings.ShowSilentAimTarget)
389 Toggles.Prediction:SetValue(SilentAimSettings.ProjectilePrediction)
390 Options.Amount:SetValue(SilentAimSettings.ProjectilePredictionAmount)
391 Options.HitChance:SetValue(SilentAimSettings.HitChance)
392 end
393 end)
394end
395
396resume(create(function()
397 RenderStepped:Connect(function()
398 if Toggles.MousePosition.Value and Toggles.aim_Enabled.Value then
399 local part = getTarget()
400 if part then
401 local root = (part.Parent and part.Parent:IsA("Model") and part.Parent.PrimaryPart) or part
402 local ViewportPoint, IsOnScreen = WorldToViewportPoint(Camera, root.Position)
403
404 mouse_box.Visible = IsOnScreen
405 mouse_box.Position = Vector2.new(ViewportPoint.X, ViewportPoint.Y)
406 else
407 mouse_box.Visible = false
408 mouse_box.Position = Vector2.new()
409 end
410 end
411
412 if Toggles.Visible.Value then
413 fov_circle.Visible = Toggles.Visible.Value
414 fov_circle.Color = Options.Color.Value
415 fov_circle.Position = getMousePosition()
416 end
417 end)
418end))
419
420-- hooks
421-- Guns are hitscan: DamageService:Bulletcast(self, origin, radius, direction, params, name)
422-- and :PierceBulletcast(self, origin, radius, direction, params). We bend `direction` toward
423-- the target (preserving its magnitude = weapon range). The cast then returns the target's
424-- hitbox, the weapon resolves the player with GetHitTarget and applies damage itself.
425--
426-- Wallbang: bending the direction alone still lets the cast stop on a wall between the muzzle
427-- and the target. When Wallbang is on we swap in a RaycastParams that ONLY includes the target
428-- character (Include filter), so the ray ignores all geometry and lands on the target's hitbox.
429-- Body damage is applied client-side, so this registers through walls.
430local function wallbangParams(character)
431 local params = RaycastParams.new()
432 params.FilterType = Enum.RaycastFilterType.Include
433 params.FilterDescendantsInstances = { character }
434 params.RespectCanCollide = false
435 params.IgnoreWater = true
436 return params
437end
438
439-- redirects a hitscan cast at the current target; returns (direction, params) to pass through
440local function aimCast(origin, direction, params)
441 if typeof(origin) ~= "Vector3" or typeof(direction) ~= "Vector3" or direction.Magnitude == 0 then
442 return direction, params
443 end
444 local part, character = getTarget()
445 if not part then return direction, params end
446
447 direction = (part.Position - origin).Unit * direction.Magnitude
448 if Toggles.Wallbang and Toggles.Wallbang.Value and character then
449 params = wallbangParams(character)
450 end
451 return direction, params
452end
453
454local shouldAim = function()
455 return Toggles.aim_Enabled.Value and not checkcaller() and CalculateChance(SilentAimSettings.HitChance)
456end
457
458if DamageService then
459 local oldBulletcast
460 oldBulletcast = hookfunction(DamageService.Bulletcast, newcclosure(function(self, origin, radius, direction, params, name)
461 if shouldAim() then
462 direction, params = aimCast(origin, direction, params)
463 end
464 return oldBulletcast(self, origin, radius, direction, params, name)
465 end))
466
467 local oldPierce
468 oldPierce = hookfunction(DamageService.PierceBulletcast, newcclosure(function(self, origin, radius, direction, params)
469 if shouldAim() then
470 direction, params = aimCast(origin, direction, params)
471 end
472 return oldPierce(self, origin, radius, direction, params)
473 end))
474end
475
476-- Projectile weapons: ProjectileService.NewProjectile(Player, Type, Position, Velocity, ...)
477-- Bend the initial Velocity toward the target (preserving speed). Optional linear lead
478-- prediction accounts for projectile travel time.
479if ProjectileService then
480 local oldNewProjectile
481 oldNewProjectile = hookfunction(ProjectileService.NewProjectile, newcclosure(function(player, projectileType, position, velocity, ...)
482 if shouldAim() and typeof(position) == "Vector3" and typeof(velocity) == "Vector3" and velocity.Magnitude > 0 then
483 local part = getTarget()
484 if part then
485 local aimPoint = part.Position
486 if Toggles.Prediction.Value then
487 local targetVelocity = part.AssemblyLinearVelocity
488 local speed = velocity.Magnitude
489 if speed > 0 then
490 local travelTime = (aimPoint - position).Magnitude / speed
491 aimPoint = aimPoint + targetVelocity * (travelTime + PredictionAmount)
492 end
493 end
494 velocity = (aimPoint - position).Unit * velocity.Magnitude
495 end
496 end
497 return oldNewProjectile(player, projectileType, position, velocity, ...)
498 end))
499end