New feature
VersusAI Pathing
Adds the special VersusAI consent card to the top of a script. It lets users choose AI movement instead of teleport-style farming, while still giving your script a normal flag to check.
VersusAI is a custom pathing system made by @dev_cammy. It does not use Roblox PathfindingService. Routes come from VersusAI's own sandbox, map snapshots, learned route memory, and movement data so the character can move more like an actual player.
local main = ui:CreateSection("Main")
main:createButton({
Name = "VersusAI Pathing",
VersusAI = true,
flagName = "UseVersusAI",
Callback = function(enabled)
if enabled then
print("VersusAI allowed - use learned routes first")
else
print("VersusAI disabled - use normal movement")
end
end,
})
Custom route engine
No Roblox PathfindingService
Supports learned farm routes
Best placed at the top of Main
Use Library.Flags["UseVersusAI"] inside your farms to decide whether to ask the backend for learned nodes or fall back to your old movement method.
Load the Library
Loads the current Versus UI library from the server. Put this near the top of your script before creating any windows or sections.
-- Load the Library
local Library = loadstring(game:HttpGet("https://versusairlines.top/scripts/NewLibrary.lua"))()
Loads from the live library URL
Includes messages, bug reports, themes, and saved flags
Open the UI
Creates the main window and returns the controller used to add tabs, sections, and elements. This also creates the floating open/close button.
local ui = Library:Setup({
Location = game.CoreGui, -- parent for the ScreenGui
OpenCloseLocation = "Top Center" -- "Top Left" | "Top Center" | "Top Right"
-- "Middle Left" | "Middle Right"
-- "Bottom Left" | "Bottom Center" | "Bottom Right"
})
Tip: Set OpenCloseLocation if you want the floating button somewhere specific. The listed positions are supported.
Starter snapshot
Base Script Template
This is my script layout: services first, library setup, anti-afk-kick, helper functions, then the documentation marker where game-specific features start.
Keep shared helpers above the marker and build the actual script below it. That makes future edits cleaner and helps avoid mixing setup code with feature code.
Plus it just means that I'll only need to cut out the stuff above the anti-afk when putting the script in the loader.
local client = game:GetService("Players").LocalPlayer
local request = (syn and syn.request) or (http and http.request) or http_request;
-- Essential services
local TweenService = game:GetService("TweenService")
local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local LightingService = game:GetService("Lighting")
local VirtualUser = game:GetService("VirtualUser")
local CoreGui = game:GetService("CoreGui")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local Workspace = game:GetService("Workspace")
local Camera = Workspace.Camera
-- Load UI
print("Loading Library...")
local Library = loadstring(game:HttpGet("https://versusairlines.top/scripts/NewLibrary.lua"))()
local Setup = Library:Setup({
Location = CoreGui,
OpenCloseLocation = "Top Center" -- Top Right, Bottom Left, Center Left, Etc
})
-- Prevent player from being idled out
client.Idled:Connect(function()
VirtualUser:Button2Down(Vector2.new(0, 0), Workspace.CurrentCamera.CFrame)
wait(1)
VirtualUser:Button2Up(Vector2.new(0, 0), Workspace.CurrentCamera.CFrame)
end)
-----------------------------------------------------------------
local function interval(tag, flag, delayTime, callback)
Library:CleanupConnectionsByTag(tag)
if not Library.Flags[flag] then return end
local last = 0
local conn = RunService.Heartbeat:Connect(function()
if not Library.Flags[flag] then
Library:CleanupConnectionsByTag(tag)
return
end
local now = os.clock()
if now - last >= delayTime then
last = now
pcall(callback)
end
end)
Library:TrackConnection(conn, tag)
end
local function notify(title, desc, style) -- "info" | "warning" | "danger"
Library:createDisplayMessage(title, desc, {
{ text = "OK" },
}, style or "info")
end
local function prettyPrint(data, indent)
indent = indent or 0
local prefix = string.rep(" ", indent)
if type(data) ~= "table" then
print(prefix .. tostring(data))
return
end
for k, v in pairs(data) do
if type(v) == "table" then
print(prefix .. tostring(k) .. " = {")
prettyPrint(v, indent + 1)
print(prefix .. "}")
else
print(prefix .. tostring(k) .. " = " .. tostring(v))
end
end
end
----------------------------------------------------------------- https://versusairlines.top/developers.html
local Main = Setup:CreateSection("Versus")
Standard services
Library setup
Anti-idle
interval helper
notify helper
For a normal release script, add your sections, labels, toggles, dropdowns, and buttons after the https://versusairlines.top/developers.html marker.
Add a Section
Adds a section to the left side of the UI. Any elements created from that section will show in the main content area.
local versus = ui:CreateSection("Versus")
local airlines = ui:CreateSection("Airlines")
Label
Adds text to the UI. Use it for headings, dividers, notes, or small explanations between features. The special style gives it a cleaner Discord-like heading look.
versus:createLabel({
Name = "hello world",
Special = true, -- renders like __***hello world***__
})
-- You can now use :Set to change the title of a label!
-- granular control
versus:createLabel({
Name = "Centered + rich",
TransparentBackground = true,
Center = true,
Bold = true,
Underline = true,
Italic = true,
})
-- or pass your own RichText
versus:createLabel({
Name = "ignored when Markup set",
Markup = "hello world",
})
Button
Clickable action. Use it for one-off actions, or pass VersusAI = true to show the special Versus AI Pathing card.
versus:createButton({
Name = "Vague Button",
Description = "Needs 'Normal Toggle' active to respond.",
Callback = function()
if Library.Flags["Jimbo"] then
print("Hello!!")
else
warn("Error: 'Normal Toggle' is off.")
end
end,
})
Toggle
A saved on/off switch. The value is stored in Library.Flags, so loops and other features can check it whenever they need to.
versus:createToggle({
Name = "Normal Toggle",
Flag = false,
flagName = "Jimbo",
Callback = function(v) print("Toggle:", v) end,
})
Slider
Lets the user pick a number between a minimum and maximum value. Useful for speed, delays, distances, amounts, and other tunable settings.
versus:createSlider({
Name = "Speed",
Description = "WalkSpeed (1-100)",
flagName = "Speed",
value = 50, -- Default value
minValue = 1,
maxValue = 100,
Callback = function(v)
game.Players.LocalPlayer.Character.Humanoid.WalkSpeed = v
end,
})
Input Box
Lets the user type a custom value. The value saves when they press Enter, making it useful for numbers, player names, IDs, or raw settings.
versus:createInputBox({
Name = "Jump Height",
flagName = "Jump",
Flag = 50,
Callback = function(v)
game.Players.LocalPlayer.Character.Humanoid.JumpHeight = tonumber(v)
end,
})
Dropdown
Shows a selectable list. It can be single-select or multi-select, and the returned object can refresh the list without rebuilding the whole UI.
local dd = versus:createDropdown({
Name = "Crew",
flagName = "CrewDrop",
Flag = {"Samantha"},
List = {"Samantha","Emma","Daisy","Timmy"},
multi = true,
Callback = print,
})
-- later:
dd:updateList({"Ava","Olivia","Mia"})
Info and Warning Icons
Most elements can show small info or warning icons on the right. Use Description for extra details and Warning when a feature needs a clear heads-up.
versus:createToggle({
Name = "God Mode",
flagName = "GodMode",
Description = "Makes you invincible (client-side).",
Warning = function() return "Server anticheat may kick you." end,
WarnIf = function() return true end, -- return false to show a disabled icon
})
Info and warning popups use the same message box style as createDisplayMessage.
Display Message
Shows a clean popup message. Use it for confirmations, warnings, changelogs, errors, or anything that needs more attention than a small label.
Library:createDisplayMessage("Heads up",
"Something changed behind the scenes.", {
{ text = "OK", color = Color3.fromRGB(82,171,255) },
{ text = "More", color = Color3.fromRGB(120,120,120), callback=function() print("more") end },
}, "info"
)
Bug Report Prompt
Opens the built-in bug report form. It sends the report to the server and can include the user's save/theme files when supported.
Library:PromptBugReport() -- opens the modal
Backspace/Esc to close
Includes key + summary + description
Can attach saves.json & theme JSONs
Themes and Customizer
Apply a preset theme or open the customizer so users can edit colors and save their own themes.
ui:UpdateUI("Dark Mode") -- apply any preset: "Light Mode", "Dark Mode", "Halloween", etc.
Library:OpenCustomizer() -- launch the interactive customizer
-- Saved theme helpers:
Library:SaveCurrentThemeAs("My Cool Theme")
Library:OverwriteSavedTheme("My Cool Theme")
Note: Special labels keep their transparent background & hidden stroke when themes change.
Presets: Light/Dark + 20+ curated sets
Saves to Versus Airlines 2.0/themes.json
Your themes in Versus Airlines 2.0/my_themes.json
Window Button and Side Icons
The library creates a floating button for opening and closing the UI. The left icon bar includes quick tools for folders, saves, bug reports, and themes.
- Folder: Opens the Versus folder (copies path if open fails)
- Trash: Deletes the current game's save (with confirm)
- Bug: Opens the bug reporter
- Customize: Opens the theme customizer
-- Visibility flag for your loops:
if Library.isClosed then
-- UI is currently visible
end
The isClosed field is a boolean you can read; it reflects the current main window visibility.
Saved Flags
Element values are kept inside Library.Flags. When the executor supports files, those values are saved per game so users keep their settings.
print(Library.Flags) -- read everything
print(Library.Flags["Jimbo"]) -- read one flag
Folder: Versus Airlines 2.0/
Save file: saves.json (per-placeId)
Connections and Cleanup
Track Roblox event connections by tag so toggles can cleanly stop their loops and listeners when disabled.
Library:CleanupConnectionsByTag("AutoFarm")
Library:TrackConnection(RunService.RenderStepped:Connect(function() end), "AutoFarm")
Sounds
Small click and pop sounds for UI feedback. They are off by default, so only enable them if the script needs sound feedback.
Library.DisableSounds = false
Library:PlaySound("Click") -- also: "Pop"
Template: Toggle Loop
A safe pattern for features that need to run while a toggle is enabled. It cleans up the old connection before starting a new one.
versus:createToggle({
Name = "Normal Toggle",
Flag = false,
flagName = "Jimbo",
Callback = function(enabled)
Library:CleanupConnectionsByTag("AutoJimbo")
if enabled then
local conn = RunService.RenderStepped:Connect(function()
if not Library.Flags["Jimbo"] then return end
print("'Normal Toggle' flag is enabled!")
end)
Library:TrackConnection(conn,"AutoJimbo")
end
end,
})
Template: Timed Heartbeat
Use this for slower repeating work, such as claiming rewards, checking shops, refreshing targets, or running anything that does not need every frame.
versus:createToggle({
Name = "Jimbo With Waiting",
Flag = false,
flagName = "waitJimbo",
Callback = function(enabled)
Library:CleanupConnectionsByTag("AutowaitJimbo")
if enabled then
local last = 0
local conn = RunService.Heartbeat:Connect(function()
if not Library.Flags["waitJimbo"] then return end
if tick() - last >= 2 then
print("Jimbo tick!")
last = tick()
end
end)
Library:TrackConnection(conn,"AutowaitJimbo")
end
end,
})
Template: Refreshing Dropdown
Keeps a dropdown updated while the game changes. This example refreshes whenever players join or leave.
local dd = versus:createDropdown({
Name = "Players",
flagName = "PlayerDrop",
List = {},
})
local function refresh()
local names = {}
for _,plr in ipairs(game.Players:GetPlayers()) do
table.insert(names,plr.Name)
end
dd:updateList(names)
end
refresh()
Library:TrackConnection(game.Players.PlayerAdded:Connect(refresh),"PlayersDD")
Library:TrackConnection(game.Players.PlayerRemoving:Connect(refresh),"PlayersDD")