--[[
Virus Border Roleplay - hub
---------------------------
Built for place 4888877755 (universe 1668757602).
Tabs
Rewards redeem the game's still-valid codes, claim the daily reward
Visuals player ESP (box, name, team colour, health, distance)
Combat silent aim through the game's own hit raycast, hitbox expander
Movement walk speed, jump power, infinite jump, noclip, fly
Farming auto-interact, auto-collect robbery money, auto-shoot, anti-AFK
Info server details, copy job id
Notes on how the combat tab works, because it is not a normal aimbot:
this game does its bullet hit detection on the CLIENT
(ReplicatedStorage.Modules.BulletHandlerClient.InstantProjectile), and only
afterwards tells the server "I hit this part" through
BulletEvent:FireServer("ApplyDamage", toolConfig, userId, part).
So instead of firing the remote ourselves, we override the raycast helper
ReplicatedStorage.Modules.WeaponUtilities.GetWeaponHitLocation and point its
target argument at the chosen player. The game then produces a completely
normal hit - same toolConfig, same remote, same server path - which is why
this stays stable where a hand-fired remote would not.
Reload-safe: run it with live-reload, not execute.
]]
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local LP = Players.LocalPlayer
-- STATE is injected by live-reload. The fallback keeps the script usable
-- under plain execute, where teardown is manual.
local STATE = STATE or {
onCleanup = function() end,
connect = function(signal, fn) return signal:Connect(fn) end,
alive = function() return true end,
override = function(tbl, key, value) tbl[key] = value end,
}
--------------------------------------------------------------------------------
-- WindUI
--------------------------------------------------------------------------------
local genv = getgenv()
local SRC_URL = "https://raw.githubusercontent.com/Footagesus/WindUI/main/dist/main.lua"
-- A previous run's window has to go before the library is loaded again,
-- otherwise WindUI refuses to make a second window / renders blank tabs.
local function nukeWindUI()
local places = {}
local okHui, hui = pcall(gethui)
if okHui and hui then table.insert(places, hui) end
table.insert(places, game:GetService("CoreGui"))
local pg = LP:FindFirstChild("PlayerGui")
if pg then table.insert(places, pg) end
for _, p in ipairs(places) do
if p then
local gui = p:FindFirstChild("WindUI")
if gui then pcall(function() gui:Destroy() end) end
end
end
end
nukeWindUI()
local rawSrc = genv.__VB_WINDUI_SRC
if not rawSrc then
local okHttp, fetched = pcall(function() return game:HttpGet(SRC_URL) end)
if not okHttp or not fetched then
return error("could not download WindUI: " .. tostring(fetched))
end
rawSrc = fetched
genv.__VB_WINDUI_SRC = rawSrc
end
-- Inside a reloaded chunk game:GetService("CoreGui") can resolve to nil, and the
-- library calls cloneref on it at load. Point that one call at PlayerGui.
local patched = rawSrc:gsub(
'game:GetService"CoreGui"',
'game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui")'
)
local okLib, WindUI = pcall(function() return loadstring(patched)() end)
if not okLib or type(WindUI) ~= "table" then
return error("WindUI failed to load: " .. tostring(WindUI))
end
genv.__VB_WINDUI = WindUI
local okHui2, hui = pcall(gethui)
local parent = (okHui2 and hui) or game:GetService("CoreGui")
if not parent then parent = LP:WaitForChild("PlayerGui") end
WindUI:SetParent(parent)
local Window = WindUI:CreateWindow({
Title = "Virus Border",
Icon = "biohazard",
Size = UDim2.fromOffset(640, 520),
Theme = "Dark",
})
local function notify(title, content, icon)
pcall(function()
WindUI:Notify({
Title = title,
Content = content,
Duration = 5,
Icon = icon or "info",
})
end)
end
--------------------------------------------------------------------------------
-- Shared state
--------------------------------------------------------------------------------
local esp = {
enabled = false,
includeTeam = false,
maxDistance = 1200,
drawings = {}, -- [player] = { box, name, dist }
renderConn = nil,
}
local aim = {
enabled = false,
fov = 220,
headOnly = true,
includeTeam = false,
maxDistance = 1200,
circle = nil,
}
local hitbox = {
enabled = false,
size = 6,
originals = setmetatable({}, { __mode = "k" }),
}
local move = {
speedEnabled = false,
speed = 32,
jumpEnabled = false,
jump = 50,
infJump = false,
noclip = false,
fly = false,
flySpeed = 60,
flyBV = nil,
noclipped = setmetatable({}, { __mode = "k" }),
}
local farm = {
autoInteract = false,
interactRadius = 12,
interactFilter = "robbery",
interactCooldown = 1,
autoCollect = false,
collectRadius = 800,
autoShoot = false,
shootDelay = 0.15,
antiAfk = false,
lastShot = 0,
cashStart = 0,
promptsFired = 0,
lastInteract = 0,
lastCollect = 0,
lastScan = 0,
lastCollected = "",
}
--------------------------------------------------------------------------------
-- Drawing helpers
--------------------------------------------------------------------------------
local hasDrawing = pcall(function()
local d = Drawing.new("Square")
d:Remove()
end)
local function newDrawing(class)
local ok, obj = pcall(Drawing.new, class)
if ok then return obj end
return nil
end
local function removeDrawing(obj)
if obj then pcall(function() obj:Remove() end) end
end
local function clearESP()
for _, set in pairs(esp.drawings) do
removeDrawing(set.box)
removeDrawing(set.name)
removeDrawing(set.dist)
end
esp.drawings = {}
end
local function teamColor(plr)
if plr.Team then
return plr.Team.TeamColor.Color
end
return Color3.fromRGB(255, 255, 255)
end
--------------------------------------------------------------------------------
-- ESP
--------------------------------------------------------------------------------
local function updateESP()
local cam = workspace.CurrentCamera
if not cam then return end
if not esp.enabled then
for _, set in pairs(esp.drawings) do
if set.box then set.box.Visible = false end
if set.name then set.name.Visible = false end
if set.dist then set.dist.Visible = false end
end
return
end
local seen = {}
local camPos = cam.CFrame.Position
for _, plr in ipairs(Players:GetPlayers()) do
if plr ~= LP and (esp.includeTeam or plr.Team ~= LP.Team) then
local char = plr.Character
local hum = char and char:FindFirstChildOfClass("Humanoid")
local hrp = char and char:FindFirstChild("HumanoidRootPart")
if hum and hrp and hum.Health > 0 then
local worldDist = (camPos - hrp.Position).Magnitude
if worldDist 0 and footPoint.Z > 0 and headOn and footOn then
local height = math.abs(footPoint.Y - headPoint.Y)
if height > 4 then
local width = height * 0.55
local topLeft = Vector2.new(headPoint.X - width / 2, headPoint.Y)
local color = teamColor(plr)
local set = esp.drawings[plr]
if not set then
set = {
box = newDrawing("Square"),
name = newDrawing("Text"),
dist = newDrawing("Text"),
}
esp.drawings[plr] = set
end
if set.box then
set.box.Visible = true
set.box.Color = color
set.box.Thickness = 1
set.box.Filled = false
set.box.Position = topLeft
set.box.Size = Vector2.new(width, height)
end
if set.name then
set.name.Visible = true
set.name.Center = true
set.name.Outline = true
set.name.Size = 14
set.name.Color = color
set.name.Position = Vector2.new(headPoint.X, headPoint.Y - 18)
set.name.Text = string.format(
"%s [%d]",
plr.DisplayName,
math.floor(hum.Health)
)
end
if set.dist then
set.dist.Visible = true
set.dist.Center = true
set.dist.Outline = true
set.dist.Size = 13
set.dist.Color = Color3.fromRGB(220, 220, 220)
set.dist.Position = Vector2.new(headPoint.X, footPoint.Y + 3)
set.dist.Text = string.format("%d studs", math.floor(worldDist))
end
seen[plr] = true
end
end
end
end
end
end
for plr, set in pairs(esp.drawings) do
if not seen[plr] then
if set.box then set.box.Visible = false end
if set.name then set.name.Visible = false end
if set.dist then set.dist.Visible = false end
end
end
end
--------------------------------------------------------------------------------
-- Silent aim
--------------------------------------------------------------------------------
local function validTarget(plr)
if plr == LP then return false end
if not aim.includeTeam and plr.Team == LP.Team then return false end
local char = plr.Character
local hum = char and char:FindFirstChildOfClass("Humanoid")
return hum ~= nil and hum.Health > 0
end
local function pickTarget()
local cam = workspace.CurrentCamera
if not cam then return nil end
local center = Vector2.new(cam.ViewportSize.X / 2, cam.ViewportSize.Y / 2)
local camPos = cam.CFrame.Position
local best, bestScore = nil, math.huge
for _, plr in ipairs(Players:GetPlayers()) do
if validTarget(plr) then
local char = plr.Character
local hrp = char:FindFirstChild("HumanoidRootPart")
local part = (aim.headOnly and char:FindFirstChild("Head")) or hrp
if part then
local worldDist = (camPos - part.Position).Magnitude
if worldDist 0 and onScreen then
local screenDist = (Vector2.new(sp.X, sp.Y) - center).Magnitude
if screenDist <= aim.fov and screenDist < bestScore then
best, bestScore = plr, screenDist
end
end
end
end
end
end
return best
end
local okModule, WeaponUtilities = pcall(function()
return require(RS:WaitForChild("Modules"):WaitForChild("WeaponUtilities"))
end)
local originalHitLocation = nil
if okModule and type(WeaponUtilities) == "table" then
originalHitLocation = WeaponUtilities.GetWeaponHitLocation
if type(originalHitLocation) == "function" then
STATE.override(WeaponUtilities, "GetWeaponHitLocation", function(origin, target, length, filter, spread)
if aim.enabled then
local plr = pickTarget()
if plr then
local char = plr.Character
local part = (aim.headOnly and char:FindFirstChild("Head"))
or char:FindFirstChild("HumanoidRootPart")
if part then
target = part.Position
spread = Vector3.zero
end
end
end
return originalHitLocation(origin, target, length, filter, spread)
end)
end
end
--------------------------------------------------------------------------------
-- Hitbox expander
--------------------------------------------------------------------------------
local function restoreHitboxes()
for part, size in pairs(hitbox.originals) do
pcall(function()
part.Size = size
part.Transparency = 0
end)
end
hitbox.originals = setmetatable({}, { __mode = "k" })
end
local function applyHitboxes()
if not hitbox.enabled then
restoreHitboxes()
return
end
local box = Vector3.new(hitbox.size, hitbox.size, hitbox.size)
for _, plr in ipairs(Players:GetPlayers()) do
if plr ~= LP then
local char = plr.Character
local hrp = char and char:FindFirstChild("HumanoidRootPart")
if hrp then
if not hitbox.originals[hrp] then
hitbox.originals[hrp] = hrp.Size
end
hrp.Size = box
hrp.Transparency = 1
end
end
end
end
--------------------------------------------------------------------------------
-- Movement
--------------------------------------------------------------------------------
local function myHumanoid()
local char = LP.Character
return char and char:FindFirstChildOfClass("Humanoid")
end
local function setNoclip(state)
local char = LP.Character
if not char then return end
if state then
for _, part in ipairs(char:GetDescendants()) do
if part:IsA("BasePart") and part.CanCollide then
move.noclipped[part] = true
part.CanCollide = false
end
end
else
for part in pairs(move.noclipped) do
pcall(function() part.CanCollide = true end)
end
move.noclipped = setmetatable({}, { __mode = "k" })
end
end
local function stopFly()
if move.flyBV then
pcall(function() move.flyBV:Destroy() end)
move.flyBV = nil
end
local hum = myHumanoid()
if hum then hum.PlatformStand = false end
end
local function startFly()
local char = LP.Character
local hrp = char and char:FindFirstChild("HumanoidRootPart")
local hum = char and char:FindFirstChildOfClass("Humanoid")
if not (hrp and hum) then return false end
stopFly()
local bv = Instance.new("BodyVelocity")
bv.MaxForce = Vector3.new(1e5, 1e5, 1e5)
bv.Velocity = Vector3.zero
bv.Parent = hrp
move.flyBV = bv
hum.PlatformStand = true
return true
end
--------------------------------------------------------------------------------
-- Farming
--
-- Nothing here invents a remote. XP is decided on the server (the XP zones only
-- sync playtime counters to the client), so the farmable resources are the ones
-- the game hands out through world interaction: proximity prompts on the vault
-- containers, sample holders and doors, and the money models those spawn.
--------------------------------------------------------------------------------
local FARM_ROOTS = {
"VaultBankRobbery",
"Sample Robbery",
"Doors",
"MissionButtons",
"ShopButtons",
"LoadoutButtons",
"SpinnerButtons",
"Experiments",
}
local promptCache = {}
local promptCooldown = setmetatable({}, { __mode = "k" })
local function promptCategory(prompt)
local node = prompt
for _ = 1, 6 do
node = node.Parent
if not node or node == workspace then break end
local name = node.Name
if name == "VaultBankRobbery" or name == "Sample Robbery" then
return "robbery"
elseif name == "Doors" then
return "doors"
elseif name == "MissionButtons" or name == "ShopButtons"
or name == "LoadoutButtons" or name == "SpinnerButtons" then
return "booths"
end
end
return "other"
end
local function refreshPrompts()
promptCache = {}
for _, rootName in ipairs(FARM_ROOTS) do
local root = workspace:FindFirstChild(rootName)
if root then
for _, d in ipairs(root:GetDescendants()) do
if d:IsA("ProximityPrompt") then
table.insert(promptCache, d)
end
end
end
end
end
local function nearbyPrompts(radius)
local char = LP.Character
local hrp = char and char:FindFirstChild("HumanoidRootPart")
if not hrp then return {} end
local out = {}
for _, prompt in ipairs(promptCache) do
local parent = prompt.Parent
if prompt.Enabled and parent and parent:IsA("BasePart") then
local dist = (hrp.Position - parent.Position).Magnitude
if dist <= math.min(radius, prompt.MaxActivationDistance) then
table.insert(out, { prompt = prompt, distance = dist, category = promptCategory(prompt) })
end
end
end
table.sort(out, function(a, b) return a.distance <b> farm.interactCooldown then
promptCooldown[entry.prompt] = os.clock()
pcall(function() fireproximityprompt(entry.prompt) end)
fired = fired + 1
farm.promptsFired = farm.promptsFired + 1
if fired >= 3 then break end
end
end
end
return fired
end
-- Prompts that hand out money: the vault's "75$ / PICK UP" container doors and
-- dropped sample bags. The vault's 5 second "Secure" prompt is a police action,
-- so it is deliberately not treated as farming.
local function isMoneyPrompt(prompt)
if promptCategory(prompt) ~= "robbery" then return false end
local object = string.upper(prompt.ObjectText or "")
local action = string.upper(prompt.ActionText or "")
return object:find("PICK UP", 1, true) ~= nil
or object:find("BAG", 1, true) ~= nil
or action:find("$", 1, true) ~= nil
end
local function moneyPrompts()
local out = {}
for _, prompt in ipairs(promptCache) do
if prompt.Enabled and prompt.Parent and prompt.Parent:IsA("BasePart") and isMoneyPrompt(prompt) then
table.insert(out, prompt)
end
end
return out
end
-- Two phases, because the server checks how far away you were when the prompt
-- fired: move next to the container on one tick, fire it on the next.
local collectPending = nil
local function autoCollect()
local char = LP.Character
local hrp = char and char:FindFirstChild("HumanoidRootPart")
if not hrp then return false end
if collectPending then
local prompt = collectPending
collectPending = nil
local parent = prompt.Parent
if prompt.Enabled and parent and parent:IsA("BasePart") then
local dist = (hrp.Position - parent.Position).Magnitude
if dist <= (prompt.MaxActivationDistance or 10) then
promptCooldown[prompt] = os.clock()
pcall(function() fireproximityprompt(prompt) end)
farm.promptsFired = farm.promptsFired + 1
farm.lastCollected = parent:GetFullName()
return true
end
end
return false
end
local best, bestDist = nil, math.huge
for _, prompt in ipairs(moneyPrompts()) do
local dist = (hrp.Position - prompt.Parent.Position).Magnitude
if dist <= farm.collectRadius and dist (best.MaxActivationDistance or 10) * 0.8 then
hrp.CFrame = CFrame.new(best.Parent.Position + Vector3.new(0, 2.5, 0))
pcall(function() hrp.AssemblyLinearVelocity = Vector3.zero end)
end
collectPending = best
return false
end
local function autoShoot()
if os.clock() - farm.lastShot 0.35 then
farm.lastInteract = os.clock()
if os.clock() - farm.lastScan > 3 then
farm.lastScan = os.clock()
refreshPrompts()
end
autoInteract()
end
if farm.autoCollect and os.clock() - farm.lastCollect > 0.7 then
farm.lastCollect = os.clock()
autoCollect()
end
if farm.autoShoot then
autoShoot()
end
end
refreshPrompts()
local cashValue = LP:FindFirstChild("Cash")
farm.cashStart = cashValue and cashValue.Value or 0
--------------------------------------------------------------------------------
-- Frame loop
--------------------------------------------------------------------------------
STATE.connect(RunService.RenderStepped, function()
updateESP()
farmTick()
-- aim FOV circle
if aim.circle then
local cam = workspace.CurrentCamera
if cam then
aim.circle.Visible = aim.enabled
aim.circle.Position = Vector2.new(cam.ViewportSize.X / 2, cam.ViewportSize.Y / 2)
aim.circle.Radius = aim.fov
end
end
-- movement
local hum = myHumanoid()
if hum then
if move.speedEnabled then
hum.WalkSpeed = move.speed
elseif hum.WalkSpeed > 16 then
hum.WalkSpeed = 16
end
if move.jumpEnabled then
hum.UseJumpPower = true
hum.JumpPower = move.jump
end
if move.noclip then
setNoclip(true)
end
if move.fly and move.flyBV then
local cam = workspace.CurrentCamera
if cam then
local dir = Vector3.zero
if UIS:IsKeyDown(Enum.KeyCode.W) then dir += cam.CFrame.LookVector end
if UIS:IsKeyDown(Enum.KeyCode.S) then dir -= cam.CFrame.LookVector end
if UIS:IsKeyDown(Enum.KeyCode.A) then dir -= cam.CFrame.RightVector end
if UIS:IsKeyDown(Enum.KeyCode.D) then dir += cam.CFrame.RightVector end
if UIS:IsKeyDown(Enum.KeyCode.Space) then dir += Vector3.yAxis end
if UIS:IsKeyDown(Enum.KeyCode.LeftControl) then dir -= Vector3.yAxis end
if dir.Magnitude > 0 then
move.flyBV.Velocity = dir.Unit * move.flySpeed
else
move.flyBV.Velocity = Vector3.zero
end
end
end
end
end)
STATE.connect(UIS.JumpRequest, function()
if move.infJump then
local hum = myHumanoid()
if hum then
hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
end)
-- Anti-idle: the usual 20 minute kick only checks for input, so a virtual click
-- is enough to keep a farming session alive.
STATE.connect(LP.Idled, function()
if not farm.antiAfk then return end
pcall(function()
local vu = game:GetService("VirtualUser")
vu:CaptureController()
vu:ClickButton2(Vector2.new())
end)
end)
-- hitbox refresh loop (cheap, four times a second)
task.spawn(function()
while STATE.alive() do
if hitbox.enabled then
applyHitboxes()
end
task.wait(0.25)
end
end)
--------------------------------------------------------------------------------
-- UI: Rewards
--------------------------------------------------------------------------------
local Events = RS:WaitForChild("Events")
local redeemEvent = Events:FindFirstChild("RedeemCode")
local dailyFn = Events:FindFirstChild("DailyRewardEvents")
and Events.DailyRewardEvents:FindFirstChild("GetDailyReward")
-- Codes the game's own Codes module still marks Valid = true.
local VALID_CODES = {
"2YRCBRN",
"HALL0W33N2025CBRN",
}
local rewardsTab = Window:Tab({ Title = "Rewards", Icon = "gift" })
rewardsTab:Paragraph({
Title = "Free rewards",
Desc = "Both of these use the game's own remotes the way its UI does.",
})
rewardsTab:Button({
Title = "Redeem active codes",
Desc = "2YRCBRN, HALL0W33N2025CBRN",
Callback = function()
if not redeemEvent then
notify("Rewards", "RedeemCode remote not found", "alert-triangle")
return
end
task.spawn(function()
for _, code in ipairs(VALID_CODES) do
if not STATE.alive() then return end
pcall(function() redeemEvent:FireServer(code) end)
notify("Code sent", code, "ticket")
task.wait(1.5)
end
end)
end,
})
rewardsTab:Button({
Title = "Claim daily reward",
Desc = "DailyRewardEvents.GetDailyReward",
Callback = function()
if not dailyFn then
notify("Rewards", "GetDailyReward remote not found", "alert-triangle")
return
end
task.spawn(function()
local ok, a, b = pcall(function() return dailyFn:InvokeServer() end)
if ok then
notify("Daily reward", tostring(a) .. " " .. tostring(b), "calendar-check")
else
notify("Daily reward failed", tostring(a), "alert-triangle")
end
end)
end,
})
--------------------------------------------------------------------------------
-- UI: Visuals
--------------------------------------------------------------------------------
local visualsTab = Window:Tab({ Title = "Visuals", Icon = "eye" })
if not hasDrawing then
visualsTab:Paragraph({
Title = "Drawing unavailable",
Desc = "This executor build does not expose Drawing, so ESP cannot draw.",
})
end
visualsTab:Toggle({
Title = "Player ESP",
Desc = "Box, name, health and distance",
Value = false,
Callback = function(state)
esp.enabled = state
if not state then clearESP() end
end,
})
visualsTab:Toggle({
Title = "Include teammates",
Desc = "Off = only players you can shoot",
Value = false,
Callback = function(state) esp.includeTeam = state end,
})
visualsTab:Slider({
Title = "ESP distance",
Desc = "Maximum studs to draw",
Value = { Min = 100, Max = 5000, Default = 1200 },
Callback = function(value) esp.maxDistance = value end,
})
--------------------------------------------------------------------------------
-- UI: Combat
--------------------------------------------------------------------------------
local combatTab = Window:Tab({ Title = "Combat", Icon = "crosshair" })
if not (okModule and originalHitLocation) then
combatTab:Paragraph({
Title = "Combat unavailable",
Desc = "Could not reach ReplicatedStorage.Modules.WeaponUtilities.",
})
end
combatTab:Paragraph({
Title = "How this works",
Desc = "Redirects the game's own client-side hit raycast, so the server sees a normal hit.",
})
combatTab:Toggle({
Title = "Silent aim",
Desc = "Redirect weapon hits to the nearest target",
Value = false,
Callback = function(state)
aim.enabled = state
if state and not aim.circle then
aim.circle = newDrawing("Circle")
if aim.circle then
aim.circle.Thickness = 1
aim.circle.Color = Color3.fromRGB(255, 90, 90)
aim.circle.Transparency = 0.6
aim.circle.Filled = false
end
end
if aim.circle then aim.circle.Visible = state end
end,
})
combatTab:Slider({
Title = "FOV",
Desc = "Pixel radius from screen centre",
Value = { Min = 30, Max = 800, Default = 220 },
Callback = function(value) aim.fov = value end,
})
combatTab:Toggle({
Title = "Head only",
Desc = "Target the Head part",
Value = true,
Callback = function(state) aim.headOnly = state end,
})
combatTab:Toggle({
Title = "Target teammates",
Desc = "Off = respect your team",
Value = false,
Callback = function(state) aim.includeTeam = state end,
})
combatTab:Slider({
Title = "Aim distance",
Value = { Min = 100, Max = 5000, Default = 1200 },
Callback = function(value) aim.maxDistance = value end,
})
combatTab:Divider()
combatTab:Toggle({
Title = "Hitbox expander",
Desc = "Enlarge other players' hitboxes",
Value = false,
Callback = function(state)
hitbox.enabled = state
if not state then restoreHitboxes() end
end,
})
combatTab:Slider({
Title = "Hitbox size",
Value = { Min = 2, Max = 20, Default = 6 },
Callback = function(value) hitbox.size = value end,
})
--------------------------------------------------------------------------------
-- UI: Movement
--------------------------------------------------------------------------------
local moveTab = Window:Tab({ Title = "Movement", Icon = "footprints" })
moveTab:Toggle({
Title = "Custom walk speed",
Value = false,
Callback = function(state) move.speedEnabled = state end,
})
moveTab:Slider({
Title = "Walk speed",
Value = { Min = 16, Max = 250, Default = 32 },
Callback = function(value) move.speed = value end,
})
moveTab:Toggle({
Title = "Custom jump power",
Value = false,
Callback = function(state) move.jumpEnabled = state end,
})
moveTab:Slider({
Title = "Jump power",
Value = { Min = 50, Max = 300, Default = 50 },
Callback = function(value) move.jump = value end,
})
moveTab:Toggle({
Title = "Infinite jump",
Value = false,
Callback = function(state) move.infJump = state end,
})
moveTab:Toggle({
Title = "Noclip",
Desc = "Walk through walls (local only)",
Value = false,
Callback = function(state)
move.noclip = state
setNoclip(state)
end,
})
moveTab:Toggle({
Title = "Fly",
Desc = "WASD to move, Space up, Left Ctrl down",
Value = false,
Callback = function(state)
move.fly = state
if state then
if not startFly() then
move.fly = false
notify("Fly", "No character to fly with", "alert-triangle")
end
else
stopFly()
end
end,
})
moveTab:Slider({
Title = "Fly speed",
Value = { Min = 10, Max = 300, Default = 60 },
Callback = function(value) move.flySpeed = value end,
})
--------------------------------------------------------------------------------
-- UI: Farming
--------------------------------------------------------------------------------
local farmTab = Window:Tab({ Title = "Farming", Icon = "wheat" })
farmTab:Toggle({
Title = "Auto-interact",
Desc = "Press nearby prompts",
Value = false,
Callback = function(state)
farm.autoInteract = state
if state then refreshPrompts() end
end,
})
farmTab:Slider({
Title = "Interact radius",
Desc = "Studs",
Value = { Min = 4, Max = 30, Default = 12 },
Callback = function(value) farm.interactRadius = value end,
})
farmTab:Dropdown({
Title = "What to press",
Values = { "all", "robbery", "doors", "booths" },
Value = "robbery",
Callback = function(value) farm.interactFilter = value end,
})
farmTab:Toggle({
Title = "Auto-collect money",
Desc = "Pick up robbery money",
Value = false,
Callback = function(state)
farm.autoCollect = state
collectPending = nil
end,
})
farmTab:Slider({
Title = "Collect radius",
Desc = "Max distance to money",
Value = { Min = 100, Max = 3000, Default = 800 },
Callback = function(value) farm.collectRadius = value end,
})
farmTab:Toggle({
Title = "Auto-shoot",
Desc = "Fire at the silent-aim target",
Value = false,
Callback = function(state)
farm.autoShoot = state
if state then
aim.enabled = true
if aim.circle then aim.circle.Visible = true end
end
end,
})
farmTab:Toggle({
Title = "Anti-AFK",
Desc = "Avoid the idle kick",
Value = false,
Callback = function(state) farm.antiAfk = state end,
})
farmTab:Button({
Title = "Farm status",
Desc = "Cash gained and prompts fired",
Callback = function()
local cash = LP:FindFirstChild("Cash")
local gained = (cash and cash.Value or 0) - farm.cashStart
local near = #nearbyPrompts(farm.interactRadius)
notify(
"Farm status",
string.format(
"Cash +%d since load | %d prompts fired | %d in range | %d money live",
gained,
farm.promptsFired,
near,
#moneyPrompts()
),
"wheat"
)
end,
})
--------------------------------------------------------------------------------
-- UI: Info
--------------------------------------------------------------------------------
local infoTab = Window:Tab({ Title = "Info", Icon = "info" })
local jobId = game.JobId
if jobId == "" then jobId = "(reserved server)" end
infoTab:Paragraph({
Title = game:GetService("MarketplaceService"):GetProductInfo(game.PlaceId).Name or "Virus Border Roleplay",
Desc = string.format(
"Place %d | Universe %d\nPlayers here: %d\nJob: %s",
game.PlaceId,
game.GameId,
#Players:GetPlayers(),
jobId
),
})
infoTab:Button({
Title = "Copy job id",
Desc = "Useful for rejoining this exact server",
Callback = function()
local ok = pcall(function() setclipboard(jobId) end)
notify("Job id", ok and "Copied to clipboard" or jobId, "copy")
end,
})
infoTab:Button({
Title = "Unload hub",
Desc = "Close menu and turn everything off",
Callback = function()
esp.enabled = false
clearESP()
aim.enabled = false
if aim.circle then aim.circle.Visible = false end
hitbox.enabled = false
restoreHitboxes()
move.speedEnabled = false
move.infJump = false
move.noclip = false
setNoclip(false)
move.fly = false
stopFly()
local hum = myHumanoid()
if hum then hum.WalkSpeed = 16 end
pcall(function() Window:Destroy() end)
nukeWindUI()
notify("Hub", "Unloaded", "power")
end,
})
--------------------------------------------------------------------------------
-- Teardown
--------------------------------------------------------------------------------
-- Console access to the same switches the menu drives:
-- getgenv().__VB.esp.enabled = true
-- getgenv().__VB.setAim(true)
getgenv().__VB = {
window = Window,
esp = esp,
aim = aim,
hitbox = hitbox,
move = move,
setESP = function(state)
esp.enabled = state
if not state then clearESP() end
end,
setAim = function(state) aim.enabled = state end,
setHitbox = function(state)
hitbox.enabled = state
if not state then restoreHitboxes() end
end,
setNoclip = setNoclip,
farm = farm,
setAutoInteract = function(state)
farm.autoInteract = state
if state then refreshPrompts() end
end,
setAutoCollect = function(state)
farm.autoCollect = state
collectPending = nil
end,
setAutoShoot = function(state)
farm.autoShoot = state
if state then aim.enabled = true end
end,
nearbyPrompts = nearbyPrompts,
moneyPrompts = moneyPrompts,
refreshPrompts = refreshPrompts,
setFly = function(state)
move.fly = state
if state then
if not startFly() then
move.fly = false
return false
end
else
stopFly()
end
return true
end,
}
STATE.onCleanup(function()
esp.enabled = false
clearESP()
aim.enabled = false
removeDrawing(aim.circle)
aim.circle = nil
hitbox.enabled = false
restoreHitboxes()
move.noclip = false
setNoclip(false)
stopFly()
local hum = myHumanoid()
if hum then
hum.WalkSpeed = 16
hum.PlatformStand = false
end
pcall(function() Window:Destroy() end)
nukeWindUI()
end)
-- WindUI lays the first tab out before the window has settled, which can leave
-- that page drawn at zero height until you click another tab. Re-selecting it
-- once after the first frames reproduces what clicking does.
task.spawn(function()
task.wait(0.25)
pcall(function() Window:SelectTab(2) end)
task.wait(0.05)
pcall(function() Window:SelectTab(1) end)
end)
notify("Virus Border", "Hub loaded - Rewards, Visuals, Combat, Movement, Farming", "biohazard")