
Keyless VerifiedUniversal

-- V3.6: polished UI, lots more fling tiers, scrollable button area + search bar
-- Keeps existing behavior: restore draggable, minimize/close, freeze, custom editor, persistent pos, scroll disables drag
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
-- ensure closed attribute is in a sane state when the script runs (fixes re-exec problem)
player:SetAttribute("FlingGuiClosed", false)
-- --------------------
-- TIER DEFINITIONS (extra tiers added)
-- --------------------
local Tiers = {
-- "Easy" family (replacing Quick Low / Quick Medium)
["Cakewalk"] = {force = 18, up = 8, dur = 0.10, spin = 12},
["Very Easy"] = {force = 35, up = 18, dur = 0.12, spin = 25},
["Easy"] = {force = 70, up = 35, dur = 0.14, spin = 50},
["Easy Plus"] = {force = 95, up = 45, dur = 0.16, spin = 70},
["Comfortable"] = {force = 120, up = 60, dur = 0.18, spin = 85},
-- baseline tiers (some original names retained and expanded)
["Low Fling"] = {force = 30, up = 20, dur = 0.30, spin = 30},
["Medium Fling"] = {force = 60, up = 40, dur = 0.40, spin = 60},
["Average"] = {force = 140, up = 72, dur = 0.20, spin = 90},
["Mid"] = {force = 200, up = 100, dur = 0.20, spin = 120},
["Hard Fling"] = {force = 300, up = 140, dur = 0.30, spin = 180},
["Very Hard"] = {force = 420, up = 190, dur = 0.32, spin = 230},
["Turbo Fling"] = {force = 180, up = 70, dur = 0.18, spin = 140},
["Insane Fling"] = {force = 160, up = 80, dur = 0.50, spin = 160},
["Extreme Fling"] = {force = 250, up = 120, dur = 0.60, spin = 220},
["Ultra Fling"] = {force = 400, up = 180, dur = 0.80, spin = 300},
["Meteor Fling"] = {force = 520, up = 200, dur = 0.90, spin = 380},
["Difficult"] = {force = 650, up = 240, dur = 0.95, spin = 420},
["Challenging"] = {force = 820, up = 300, dur = 1.00, spin = 520},
-- God-tier family
["God Fling"] = {force = 1000, up = 350, dur = 1.00, spin = 600},
["Apex Fling"] = {force = 1400, up = 700, dur = 1.20, spin = 700},
["Titan Fling"] = {force = 1800, up = 900, dur = 1.40, spin = 820},
["Colossus Fling"] = {force = 2400, up = 1100, dur = 1.60, spin = 1000},
["Leviathan Fling"] = {force = 3200, up = 1600, dur = 1.80, spin = 1300},
["Omega Fling"] = {force = 4000, up = 2000, dur = 2.00, spin = 1600},
-- Cosmic family
["Void Fling"] = {force = 6000, up = 3000, dur = 2.40, spin = 2000},
["Nebula Fling"] = {force = 9000, up = 4500, dur = 2.80, spin = 2600},
["Nova Fling"] = {force = 14000, up = 8000, dur = 3.20, spin = 3400},
["Singularity"] = {force = 22000, up = 12000, dur = 3.80, spin = 4400},
["Infinity Fling"] = {force = 35000, up = 20000, dur = 4.50, spin = 6000},
-- advanced cosmic/god extremes (added many)
["Eternity Fling"] = {force = 50000, up = 26000, dur = 5.00, spin = 7200},
["Armageddon Fling"] = {force = 70000, up = 36000, dur = 5.50, spin = 9200},
["Cataclysm Fling"] = {force = 100000, up = 56000, dur = 6.00, spin = 12500},
["Oblivion Fling"] = {force = 140000, up = 84000, dur = 6.50, spin = 16000},
["Transcendence"] = {force = 200000, up = 120000, dur = 7.00, spin = 20000},
["Ascension Fling"] = {force = 280000, up = 160000, dur = 7.50, spin = 25000},
-- search-friendly & absurd extremes
["Apotheosis"] = {force = 380000, up = 220000, dur = 8.00, spin = 32000},
["Quantum Fling"] = {force = 500000, up = 300000, dur = 9.00, spin = 42000},
["Purgatory Fling"] = {force = 750000, up = 420000, dur = 10.0, spin = 56000},
["Empyrean Fling"] = {force = 1100000,up = 700000, dur = 11.0, spin = 78000},
-- extreme-end "nightmare" tiers
["Omega II"] = {force = 1600000, up = 900000, dur = 12.0, spin = 120000},
["Cosmos Fling"] = {force = 2500000, up = 1500000,dur = 13.0, spin = 180000},
["Mythic Fling"] = {force = 4000000, up = 2400000,dur = 14.0, spin = 260000},
["Absolute Fling"] = {force = 7000000, up = 4200000,dur = 16.0, spin = 420000},
["Singularity Prime"] = {force = 12000000,up = 7000000,dur = 18.0, spin = 700000},
["Deus Fling"] = {force = 25000000,up = 14000000,dur = 20.0, spin = 1200000},
-- chart-named extras requested (terrifying / catastrophic / etc)
["Terrifying"] = {force = 900000, up = 520000, dur = 12.5, spin = 260000},
["Catastrophic"] = {force = 1800000, up = 1000000,dur = 14.0, spin = 420000},
["Top"] = {force = 5000000, up = 3000000,dur = 16.0, spin = 700000},
["Nightmare"] = {force = 9000000, up = 5200000,dur = 18.0, spin = 1000000},
["Impossible"] = {force = 20000000,up = 12000000,dur = 22.0, spin = 2000000},
["Absurd"] = {force = 50000000,up = 30000000,dur = 30.0, spin = 5000000},
-- Random tier placeholder (actual random stats generated on use)
["Random"] = {force = 0, up = 0, dur = 0, spin = 0},
}
-- Default custom
local customName = "Custom Fling"
local CustomStats = {force = 80, up = 40, dur = 0.40, spin = 80}
-- cooldown
local COOLDOWN = 0.12
local lastUsed = {}
local function safeButtonPress(name)
local t = tick()
if lastUsed[name] and (t - lastUsed[name] < COOLDOWN) then return false end
lastUsed[name] = t
return true
end
-- Freeze state
local isFrozen = false
local function clearRootForces()
if not humanoidRootPart then return end
for _, child in ipairs(humanoidRootPart:GetChildren()) do
if child:IsA("BodyVelocity") or child:IsA("BodyAngularVelocity") then
pcall(function() child:Destroy() end)
end
end
end
local function freezeCharacter()
isFrozen = true
clearRootForces()
pcall(function()
if humanoid then humanoid.PlatformStand = true end
if humanoidRootPart then humanoidRootPart.Anchored = true end
end)
end
local function unfreezeCharacter()
isFrozen = false
pcall(function()
if humanoidRootPart then humanoidRootPart.Anchored = false end
if humanoid then humanoid.PlatformStand = false end
end)
end
-- Generic fling (forward)
local function flingGeneric(force, upward, duration, spin)
if isFrozen then return end
if not humanoid or humanoid.Health <= 0 then return end
if not humanoidRootPart then return end
local forward = humanoidRootPart.CFrame.LookVector
local bv = Instance.new("BodyVelocity")
bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bv.Velocity = (forward * force) + Vector3.new(0, upward, 0)
bv.Parent = humanoidRootPart
local bav = Instance.new("BodyAngularVelocity")
bav.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
bav.AngularVelocity = Vector3.new(math.random(-math.floor(spin), math.floor(spin)), math.random(-math.floor(spin), math.floor(spin)), math.random(-math.floor(spin), math.floor(spin)))
bav.Parent = humanoidRootPart
Debris:AddItem(bv, duration)
Debris:AddItem(bav, duration)
end
-- function to generate random (unbounded-style) stats
local function generateRandomStats()
-- seed with current tick for variety
local seed = math.floor(tick() * 1000) % 2147483647
math.randomseed(seed)
-- random ranges intentionally huge to emulate "no limit" feel (adjust if needed)
local maxForce = 50000000 -- 50 million
local maxUp = 30000000 -- 30 million
local maxSpin = 5000000 -- 5 million
local maxDur = 60 -- up to 60 seconds (long)
local force = math.random() * maxForce
local up = math.random() * maxUp
local spin = math.random() * maxSpin
local dur = 0.05 + (math.random() * maxDur)
-- tiny safety clamps (ensure duration not zero)
if dur <= 0 then dur = 0.05 end
return force, up, dur, math.floor(spin)
end
-- save/load position
local function saveFramePositionToPlayer(frame)
local sv = player:FindFirstChild("FlingGuiPos")
if not sv then
sv = Instance.new("StringValue")
sv.Name = "FlingGuiPos"
sv.Parent = player
end
local p = frame.Position
sv.Value = string.format("%.6f;%d;%.6f;%d", p.X.Scale, p.X.Offset, p.Y.Scale, p.Y.Offset)
end
local function loadFramePositionFromPlayer()
local sv = player:FindFirstChild("FlingGuiPos")
if not sv then
return UDim2.new(1, -160, 0.55, 0)
end
local ok, a,b,c,d = pcall(function()
local s = sv.Value
local xS,xO,yS,yO = string.match(s, "([%d%.%-]+);([%d%-]+);([%d%.%-]+);([%d%-]+)")
return tonumber(xS), tonumber(xO), tonumber(yS), tonumber(yO)
end)
if ok and a and b and c and d then
return UDim2.new(a, b, c, d)
end
return UDim2.new(1, -160, 0.55, 0)
end
-- Create GUI (respects player attribute "FlingGuiClosed")
local function createFlingGui()
-- if player closed earlier, do not recreate
if player:GetAttribute("FlingGuiClosed") == true then
return
end
-- ensure no duplicates (destroy any old one)
if player.PlayerGui:FindFirstChild("FlingGui") then
player.PlayerGui.FlingGui:Destroy()
end
-- make gui
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "FlingGui"
screenGui.ResetOnSpawn = false
screenGui.Parent = player.PlayerGui
-- mark as not closed
player:SetAttribute("FlingGuiClosed", false)
-- ordered button list (controls which buttons show and in what order)
local order = {
"Cakewalk","Very Easy","Easy","Easy Plus","Comfortable",
"Low Fling","Medium Fling","Average","Mid","Hard Fling","Very Hard",
"Turbo Fling","Insane Fling","Extreme Fling","Ultra Fling","Meteor Fling",
"Difficult","Challenging",
"God Fling","Apex Fling","Titan Fling","Colossus Fling","Leviathan Fling","Omega Fling",
"Void Fling","Nebula Fling","Nova Fling","Singularity","Infinity Fling",
"Eternity Fling","Armageddon Fling","Cataclysm Fling","Oblivion Fling",
"Transcendence","Ascension Fling","Apotheosis","Quantum Fling","Purgatory Fling","Empyrean Fling",
"Omega II","Cosmos Fling","Mythic Fling","Absolute Fling","Singularity Prime","Deus Fling",
"Terrifying","Catastrophic","Top","Nightmare","Impossible","Absurd",
"Random" -- keep Random in order but it will be displayed as bottom grouped with controls
}
-- layout constants
local startY = 34
local spacing = 32
local buttonHeight = 28
local visibleButtons = 6 -- how many buttons visible at once before scroll
-- main frame (fixed height; buttons live inside ScrollingFrame)
local frame = Instance.new("Frame")
frame.Name = "MainFrame"
frame.Size = UDim2.new(0, 200, 0, 40 + visibleButtons * spacing + 36) -- slightly wider
frame.Position = loadFramePositionFromPlayer()
frame.BackgroundColor3 = Color3.fromRGB(22,22,22)
frame.BorderSizePixel = 0
frame.Active = true
frame.Draggable = true
frame.Parent = screenGui
-- nicer rounded corners
local frameCorner = Instance.new("UICorner", frame)
frameCorner.CornerRadius = UDim.new(0, 10)
local frameStroke = Instance.new("UIStroke", frame)
frameStroke.Color = Color3.fromRGB(50,50,50)
frameStroke.Thickness = 1
frameStroke.Transparency = 0.6
-- persist position
frame:GetPropertyChangedSignal("Position"):Connect(function()
pcall(function() saveFramePositionToPlayer(frame) end)
end)
-- helper to temporarily disable/enable dragging
local dragDisabledCount = 0
local function disableDrag()
dragDisabledCount = dragDisabledCount + 1
frame.Draggable = false
end
local function enableDrag()
dragDisabledCount = math.max(0, dragDisabledCount - 1)
if dragDisabledCount == 0 then
frame.Draggable = true
end
end
-- title area
local titleBg = Instance.new("Frame")
titleBg.Size = UDim2.new(1, 0, 0, 36)
titleBg.Position = UDim2.new(0, 0, 0, 0)
titleBg.BackgroundTransparency = 0.08
titleBg.BackgroundColor3 = Color3.fromRGB(12,12,12)
titleBg.BorderSizePixel = 0
titleBg.Parent = frame
local titleCorner = Instance.new("UICorner", titleBg)
titleCorner.CornerRadius = UDim.new(0, 10)
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -120, 1, 0)
title.Position = UDim2.new(0, 12, 0, 6)
title.BackgroundTransparency = 1
title.Text = "Fling Menu — V3.6"
title.Font = Enum.Font.GothamBold
title.TextSize = 15
title.TextColor3 = Color3.fromRGB(230,230,230)
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = titleBg
-- CLOSE & MINIMIZE
local closeBtn = Instance.new("TextButton")
closeBtn.Size = UDim2.new(0, 28, 0, 24)
closeBtn.Position = UDim2.new(1, -34, 0, 6)
closeBtn.AnchorPoint = Vector2.new(0,0)
closeBtn.BackgroundColor3 = Color3.fromRGB(36,36,36)
closeBtn.BorderSizePixel = 0
closeBtn.Font = Enum.Font.SourceSansBold
closeBtn.Text = "X"
closeBtn.TextScaled = true
closeBtn.TextColor3 = Color3.fromRGB(255,255,255)
closeBtn.Parent = titleBg
local closeCorner = Instance.new("UICorner", closeBtn)
closeCorner.CornerRadius = UDim.new(0,6)
closeBtn.MouseButton1Click:Connect(function()
player:SetAttribute("FlingGuiClosed", true)
pcall(function() screenGui:Destroy() end)
end)
local minimizeBtn = Instance.new("TextButton")
minimizeBtn.Size = UDim2.new(0, 28, 0, 24)
minimizeBtn.Position = UDim2.new(1, -68, 0, 6)
minimizeBtn.AnchorPoint = Vector2.new(0,0)
minimizeBtn.BackgroundColor3 = Color3.fromRGB(36,36,36)
minimizeBtn.BorderSizePixel = 0
minimizeBtn.Font = Enum.Font.SourceSansBold
minimizeBtn.Text = "—"
minimizeBtn.TextScaled = true
minimizeBtn.TextColor3 = Color3.fromRGB(255,255,255)
minimizeBtn.Parent = titleBg
local miniCorner = Instance.new("UICorner", minimizeBtn)
miniCorner.CornerRadius = UDim.new(0,6)
local minimized = false
local restoreBtn = nil
local function createRestoreButton(atPos)
if restoreBtn and restoreBtn.Parent then
restoreBtn:Destroy()
restoreBtn = nil
end
local rFrame = Instance.new("Frame")
rFrame.Name = "FlingRestore"
rFrame.Size = UDim2.new(0, 64, 0, 64)
rFrame.Position = atPos or UDim2.new(1, -160, 0.55, 0)
rFrame.BackgroundColor3 = Color3.fromRGB(34,34,34)
rFrame.BorderSizePixel = 0
rFrame.Active = true
rFrame.Parent = screenGui
local rCorner = Instance.new("UICorner", rFrame)
rCorner.CornerRadius = UDim.new(0, 12)
local rBtn = Instance.new("TextButton")
rBtn.Size = UDim2.new(1,0,1,0)
rBtn.Position = UDim2.new(0,0,0,0)
rBtn.BackgroundTransparency = 1
rBtn.Font = Enum.Font.GothamBold
rBtn.Text = "☐"
rBtn.TextSize = 28
rBtn.TextColor3 = Color3.fromRGB(230,230,230)
rBtn.Parent = rFrame
local dragInput, dragStart, startPos = nil, nil, nil
local function clampToViewport(x,y,frameObj)
local vp = workspace.CurrentCamera and workspace.CurrentCamera.ViewportSize or Vector2.new(1920,1080)
local absSize = frameObj.AbsoluteSize
local maxX = math.max(0, vp.X - absSize.X)
local maxY = math.max(0, vp.Y - absSize.Y)
return math.clamp(x, 0, maxX), math.clamp(y, 0, maxY)
end
local function update(input)
if not dragStart or not startPos then return end
local delta = input.Position - dragStart
local newX = startPos.x + delta.X
local newY = startPos.y + delta.Y
newX, newY = clampToViewport(newX, newY, rFrame)
rFrame.Position = UDim2.new(0, newX, 0, newY)
end
rBtn.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
dragInput = input
dragStart = input.Position
startPos = { x = rFrame.AbsolutePosition.X, y = rFrame.AbsolutePosition.Y }
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragInput = nil
dragStart = nil
startPos = nil
end
end)
end
end)
UIS.InputChanged:Connect(function(input)
if input == dragInput then update(input) end
end)
rBtn.MouseButton1Click:Connect(function()
if frame and frame.Parent then
frame.Visible = true
pcall(function()
frame.Position = rFrame.Position
saveFramePositionToPlayer(frame)
end)
end
if screenGui:FindFirstChild("CustomEditorFrame") then pcall(function() screenGui.CustomEditorFrame.Visible = false end) end
pcall(function() rFrame:Destroy() end)
restoreBtn = nil
minimized = false
end)
rFrame:GetPropertyChangedSignal("AbsolutePosition"):Connect(function() pcall(function() saveFramePositionToPlayer(rFrame) end) end)
restoreBtn = rFrame
end
minimizeBtn.MouseButton1Click:Connect(function()
if not minimized then
frame.Visible = false
if screenGui:FindFirstChild("CustomEditorFrame") then screenGui.CustomEditorFrame.Visible = false end
local pos = (function() local p = frame.Position; return UDim2.new(p.X.Scale, p.X.Offset, p.Y.Scale, p.Y.Offset) end)()
createRestoreButton(pos)
minimized = true
else
if restoreBtn and restoreBtn.Parent then
local textBtn = restoreBtn:FindFirstChildOfClass("TextButton")
if textBtn then textBtn:CaptureFocus(); textBtn:MouseButton1Click() end
end
minimized = false
end
end)
-- --------------------
-- SEARCH BAR
-- --------------------
local searchBox = Instance.new("TextBox")
searchBox.Size = UDim2.new(1, -96, 0, 22)
searchBox.Position = UDim2.new(0, 12, 0, 40)
searchBox.PlaceholderText = "Search fling..."
searchBox.Text = ""
searchBox.Font = Enum.Font.Gotham
searchBox.TextSize = 14
searchBox.ClearTextOnFocus = false
searchBox.BackgroundColor3 = Color3.fromRGB(28,28,28)
searchBox.TextColor3 = Color3.fromRGB(230,230,230)
searchBox.Parent = frame
local sbCorner = Instance.new("UICorner", searchBox)
sbCorner.CornerRadius = UDim.new(0,6)
local searchIcon = Instance.new("TextLabel")
searchIcon.Size = UDim2.new(0, 20, 0, 20)
searchIcon.Position = UDim2.new(1, -72, 0, 42)
searchIcon.BackgroundTransparency = 1
searchIcon.Text = "🔎"
searchIcon.Font = Enum.Font.SourceSans
searchIcon.TextScaled = true
searchIcon.Parent = frame
-- --------------------
-- SCROLLING BUTTON AREA
-- --------------------
local scrollFrame = Instance.new("ScrollingFrame")
scrollFrame.Name = "ButtonsScroll"
scrollFrame.Size = UDim2.new(1, -12, 1, -(48 + 28)) -- leave room for title + search and bottom
scrollFrame.Position = UDim2.new(0, 6, 0, startY + 18)
scrollFrame.BackgroundTransparency = 1
scrollFrame.BorderSizePixel = 0
scrollFrame.CanvasSize = UDim2.new(0,0,0,0)
scrollFrame.ScrollBarThickness = 8
scrollFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y
scrollFrame.ScrollingDirection = Enum.ScrollingDirection.Y
scrollFrame.Parent = frame
local list = Instance.new("UIListLayout")
list.SortOrder = Enum.SortOrder.LayoutOrder
list.Padding = UDim.new(0, 6)
list.Parent = scrollFrame
local topPad = Instance.new("Frame")
topPad.Size = UDim2.new(1,0,0,6)
topPad.BackgroundTransparency = 1
topPad.BorderSizePixel = 0
topPad.Parent = scrollFrame
-- styling function (choose color by name/category from your chart)
local function styleForName(name)
-- explicit Random style: black + icon
if name == "Random" then
return { color = Color3.fromRGB(8,8,8), icon = "◼" }
end
-- chart-based colors (no emoji)
-- Easy family
if name:match("Cakewalk") or name:match("Very Easy") then
return { color = Color3.fromRGB(200, 245, 200) } -- pale light green
elseif name:match("^Easy") or name:match("Comfortable") or name:match("Easy Plus") then
return { color = Color3.fromRGB(80, 200, 120) } -- green
elseif name:match("Average") then
return { color = Color3.fromRGB(250, 220, 110) } -- yellow
elseif name:match("Mid") or name:match("^Medium") then
return { color = Color3.fromRGB(255, 170, 90) } -- orange (mid)
elseif name:match("Hard") and not name:match("Very Hard") then
return { color = Color3.fromRGB(255, 140, 80) } -- orange
elseif name:match("Very Hard") then
return { color = Color3.fromRGB(220, 100, 40) } -- dark orange
elseif name:match("Difficult") then
return { color = Color3.fromRGB(220, 60, 60) } -- red
elseif name:match("Challenging") then
return { color = Color3.fromRGB(170, 30, 30) } -- dark red
elseif name:match("High") or name:match("^Apex") then
return { color = Color3.fromRGB(180, 40, 40) } -- pressure zone red
elseif name:match("Intense") or name:match("Remorseless") then
return { color = Color3.fromRGB(220, 60, 120) } -- hot pinkish
elseif name:match("Arduous") or name:match("Nightmare") then
return { color = Color3.fromRGB(140, 80, 200) } -- purple
elseif name:match("Insane") then
return { color = Color3.fromRGB(90, 140, 220) } -- blue
elseif name:match("^Extreme") and not name:match("Extreme Fling") then
return { color = Color3.fromRGB(130, 200, 240) } -- light blue
elseif name:match("Extreme Fling") then
return { color = Color3.fromRGB(70,140,220) } -- darker blue
elseif name:match("Terrifying") then
return { color = Color3.fromRGB(80, 220, 220) } -- cyan
elseif name:match("Catastrophic") then
return { color = Color3.fromRGB(220,220,230) } -- pale white/gray
elseif name:match("Top") or name:match("Impossible") then
return { color = Color3.fromRGB(24,24,24) } -- black/dark
elseif name:match("Nightmare") then
return { color = Color3.fromRGB(120,40,160) } -- dark purple
elseif name:match("Absurd") then
return { color = Color3.fromRGB(10,10,10) } -- near-black
end
-- fallback: use magnitude-based buckets (original behavior for cosmic/god)
local stats = Tiers[name]
if not stats then
return { color = Color3.fromRGB(38,38,38) }
end
local f = stats.force
if f < 200 then
return { color = Color3.fromRGB(75,170,255) } -- quick-ish blue
elseif f < 2000 then
return { color = Color3.fromRGB(60,180,90) } -- green
elseif f < 10000 then
return { color = Color3.fromRGB(220,180,60) } -- gold
elseif f < 200000 then
return { color = Color3.fromRGB(150,80,220) } -- cosmic purple
else
return { color = Color3.fromRGB(200,60,60) } -- extreme/ultimate red
end
end
-- helper to create one button inside scrollFrame with rounded corners + stroke
local buttonsByName = {} -- store refs + meta for filtering
local function makeScrollButton(text, callback)
local info = styleForName(text) or { color = Color3.fromRGB(38,38,38) }
local btn = Instance.new("TextButton")
btn.Size = UDim2.new(1, -10, 0, buttonHeight)
btn.BackgroundColor3 = info.color
btn.BorderSizePixel = 0
btn.Font = Enum.Font.Gotham
btn.TextScaled = true
-- pick readable text color (dark on bright, light on dark)
local avg = (info.color.R + info.color.G + info.color.B) / 3
btn.TextColor3 = (avg > 0.5) and Color3.fromRGB(24,24,24) or Color3.fromRGB(235,235,235)
local textToShow = text
if info.icon then textToShow = (info.icon .. " " .. text) end
btn.Text = textToShow
btn.Parent = scrollFrame
local corner = Instance.new("UICorner", btn)
corner.CornerRadius = UDim.new(0,6)
local stroke = Instance.new("UIStroke", btn)
stroke.Color = Color3.fromRGB(48,48,48)
stroke.Thickness = 1
stroke.Transparency = 0.6
btn.MouseButton1Click:Connect(function()
if not safeButtonPress(text) then return end
btn.BackgroundTransparency = 0.2
task.delay(0.08, function() if btn then btn.BackgroundTransparency = 0 end end)
callback()
end)
buttonsByName[text] = { btn = btn, name = text }
return btn
end
-- create buttons from order
for i, name in ipairs(order) do
local stats = Tiers[name]
if stats and name ~= "Random" then
makeScrollButton(name, function()
flingGeneric(stats.force, stats.up, stats.dur, stats.spin)
end)
elseif name == "Random" then
-- create placeholder now; actual Random button will be created later next to Freeze/Custom for bottom alignment
-- (we'll skip creating a list entry here so it doesn't appear twice)
else
makeScrollButton(name, function() end)
end
end
-- custom and freeze buttons at end (use neutral color)
local neutralColor = Color3.fromRGB(38,38,38)
local function makeNeutralButton(text, callback)
local btn = Instance.new("TextButton")
btn.Size = UDim2.new(1, -10, 0, buttonHeight)
btn.BackgroundColor3 = neutralColor
btn.BorderSizePixel = 0
btn.Font = Enum.Font.Gotham
btn.TextScaled = true
btn.TextColor3 = Color3.fromRGB(235,235,235)
btn.Text = text
btn.Parent = scrollFrame
local corner = Instance.new("UICorner", btn)
corner.CornerRadius = UDim.new(0,6)
local stroke = Instance.new("UIStroke", btn)
stroke.Color = Color3.fromRGB(58,58,58)
stroke.Thickness = 1
stroke.Transparency = 0.7
btn.MouseButton1Click:Connect(function()
if not safeButtonPress(text) then return end
btn.BackgroundTransparency = 0.45
task.delay(0.08, function() if btn then btn.BackgroundTransparency = 0 end end)
callback()
end)
return btn
end
local customBtn = makeNeutralButton(customName, function()
flingGeneric(CustomStats.force, CustomStats.up, CustomStats.dur, CustomStats.spin)
end)
customBtn.Name = "CustomBtn"
buttonsByName[customName] = { btn = customBtn, name = customName }
local freezeBtn = makeNeutralButton("Freeze ❄️", function()
if isFrozen then
unfreezeCharacter()
pcall(function() freezeBtn.Text = "Freeze ❄️" end)
else
freezeCharacter()
pcall(function() freezeBtn.Text = "Unfreeze ❄️" end)
end
end)
freezeBtn.Name = "FreezeBtn"
buttonsByName["Freeze ❄️"] = { btn = freezeBtn, name = "Freeze ❄️" }
-- RANDOM button (black) — bottom, next to Freeze & Custom
local function makeRandomButton()
local info = { color = Color3.fromRGB(8,8,8), icon = "◼" }
local btn = Instance.new("TextButton")
btn.Size = UDim2.new(1, -10, 0, buttonHeight)
btn.BackgroundColor3 = info.color
btn.BorderSizePixel = 0
btn.Font = Enum.Font.Gotham
btn.TextScaled = true
btn.TextColor3 = Color3.fromRGB(235,235,235)
btn.Text = (info.icon .. " Random")
btn.Parent = scrollFrame
local corner = Instance.new("UICorner", btn)
corner.CornerRadius = UDim.new(0,6)
local stroke = Instance.new("UIStroke", btn)
stroke.Color = Color3.fromRGB(28,28,28)
stroke.Thickness = 1
stroke.Transparency = 0.5
btn.MouseButton1Click:Connect(function()
if not safeButtonPress("Random") then return end
-- generate random stats and fling
local f,u,d,s = generateRandomStats()
-- show a tiny visual flash by temporarily changing transparency
btn.BackgroundTransparency = 0.2
task.delay(0.08, function() if btn then btn.BackgroundTransparency = 0 end end)
flingGeneric(f, u, d, s)
end)
return btn
end
local randomBtn = makeRandomButton()
buttonsByName["Random"] = { btn = randomBtn, name = "Random" }
-- search filter function (case-insensitive substring)
local function filterButtons(query)
query = tostring(query or ""):lower()
for name, meta in pairs(buttonsByName) do
local btn = meta.btn
if not btn then
-- skip
else
if query == "" then
btn.Visible = true
else
local ok = (string.find(name:lower(), query, 1, true) ~= nil)
btn.Visible = ok
end
end
end
end
-- hook search input (live)
searchBox:GetPropertyChangedSignal("Text"):Connect(function()
local q = searchBox.Text or ""
filterButtons(q)
end)
-- pressing ESC clears search
searchBox.Focused:Connect(function()
local conn
conn = UIS.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.KeyCode == Enum.KeyCode.Escape then
searchBox.Text = ""
filterButtons("")
conn:Disconnect()
end
end)
end)
-- --------------------
-- SCROLL HANDLING: disable dragging while user scrolls
-- --------------------
local wheelDebounce = 0
UIS.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseWheel then
disableDrag()
wheelDebounce = tick()
task.spawn(function()
task.wait(0.25)
if tick() - wheelDebounce >= 0.25 then
enableDrag()
end
end)
end
end)
scrollFrame.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
disableDrag()
local conn
conn = input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
enableDrag()
conn:Disconnect()
end
end)
end
end)
scrollFrame.MouseEnter:Connect(function() disableDrag() end)
scrollFrame.MouseLeave:Connect(function() enableDrag() end)
-- gear (moved under title)
local gear = Instance.new("TextButton")
gear.Size = UDim2.new(0,28,0,28)
gear.Position = UDim2.new(0,6,0,36)
gear.BackgroundColor3 = Color3.fromRGB(30,30,30)
gear.BorderSizePixel = 0
gear.Font = Enum.Font.SourceSans
gear.Text = "⚙"
gear.TextScaled = true
gear.TextColor3 = Color3.fromRGB(255,255,255)
gear.Parent = frame
local gearCorner = Instance.new("UICorner", gear)
gearCorner.CornerRadius = UDim.new(0,6)
-- external editFrame (sibling so it sits outside) - fixed name
local editFrame = Instance.new("Frame")
editFrame.Name = "CustomEditorFrame"
editFrame.Size = UDim2.new(0,200,0,160)
editFrame.Position = UDim2.new(frame.Position.X.Scale, frame.Position.X.Offset - (200 + 8), frame.Position.Y.Scale, frame.Position.Y.Offset)
editFrame.BackgroundTransparency = 0.02
editFrame.BackgroundColor3 = Color3.fromRGB(16,16,16)
editFrame.BorderSizePixel = 0
editFrame.Visible = false
editFrame.Parent = screenGui
local editCorner = Instance.new("UICorner", editFrame)
editCorner.CornerRadius = UDim.new(0,8)
local function updateEditPosition()
local fx = frame.Position.X.Scale
local fxoff = frame.Position.X.Offset
local fy = frame.Position.Y.Scale
local fyoff = frame.Position.Y.Offset
local newXoff = fxoff - (editFrame.Size.X.Offset + 8)
editFrame.Position = UDim2.new(fx, newXoff, fy, fyoff)
end
frame:GetPropertyChangedSignal("Position"):Connect(function() pcall(updateEditPosition) end)
-- simple editor contents (unchanged behavior)
local editTitle = Instance.new("TextLabel")
editTitle.Size = UDim2.new(1,0,0,26)
editTitle.Position = UDim2.new(0,0,0,6)
editTitle.BackgroundTransparency = 1
editTitle.Text = "Custom Editor"
editTitle.Font = Enum.Font.GothamBold
editTitle.TextSize = 14
editTitle.TextColor3 = Color3.fromRGB(240,240,240)
editTitle.Parent = editFrame
local function createLabelTextbox(y, labelText, default)
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(0.42,0,0,18)
lbl.Position = UDim2.new(0,6,0,y)
lbl.BackgroundTransparency = 1
lbl.Text = labelText
lbl.Font = Enum.Font.Gotham
lbl.TextSize = 12
lbl.TextColor3 = Color3.fromRGB(200,200,200)
lbl.Parent = editFrame
local tb = Instance.new("TextBox")
tb.Size = UDim2.new(0.56,-10,0,18)
tb.Position = UDim2.new(0.42,8,0,y)
tb.BackgroundColor3 = Color3.fromRGB(28,28,28)
tb.TextColor3 = Color3.fromRGB(240,240,240)
tb.Text = tostring(default)
tb.Font = Enum.Font.Gotham
tb.TextSize = 12
tb.ClearTextOnFocus = false
tb.Parent = editFrame
local tbCorner = Instance.new("UICorner", tb)
tbCorner.CornerRadius = UDim.new(0,4)
return tb
end
local nameLabel = Instance.new("TextLabel")
nameLabel.Size = UDim2.new(0.42,0,0,18)
nameLabel.Position = UDim2.new(0,6,0,36)
nameLabel.BackgroundTransparency = 1
nameLabel.Text = "Name"
nameLabel.Font = Enum.Font.Gotham
nameLabel.TextSize = 12
nameLabel.TextColor3 = Color3.fromRGB(200,200,200)
nameLabel.Parent = editFrame
local nameBox = Instance.new("TextBox")
nameBox.Size = UDim2.new(0.56,-10,0,18)
nameBox.Position = UDim2.new(0.42,8,0,36)
nameBox.BackgroundColor3 = Color3.fromRGB(28,28,28)
nameBox.TextColor3 = Color3.fromRGB(240,240,240)
nameBox.Text = customName
nameBox.Font = Enum.Font.Gotham
nameBox.TextSize = 12
nameBox.ClearTextOnFocus = false
nameBox.Parent = editFrame
local nbCorner = Instance.new("UICorner", nameBox)
nbCorner.CornerRadius = UDim.new(0,4)
local forceBox = createLabelTextbox(64, "Force", CustomStats.force)
local upBox = createLabelTextbox(88, "Up", CustomStats.up)
local durLabel = Instance.new("TextLabel")
durLabel.Size = UDim2.new(0.28,0,0,18)
durLabel.Position = UDim2.new(0,6,0,112)
durLabel.BackgroundTransparency = 1
durLabel.Text = "Dur"
durLabel.Font = Enum.Font.Gotham
durLabel.TextSize = 12
durLabel.TextColor3 = Color3.fromRGB(200,200,200)
durLabel.Parent = editFrame
local durBox = Instance.new("TextBox")
durBox.Size = UDim2.new(0.28,-6,0,18)
durBox.Position = UDim2.new(0.28,4,0,112)
durBox.BackgroundColor3 = Color3.fromRGB(28,28,28)
durBox.TextColor3 = Color3.fromRGB(240,240,240)
durBox.Text = tostring(CustomStats.dur)
durBox.Font = Enum.Font.Gotham
durBox.TextSize = 12
durBox.ClearTextOnFocus = false
durBox.Parent = editFrame
local durCorner = Instance.new("UICorner", durBox)
durCorner.CornerRadius = UDim.new(0,4)
local spinLabel = Instance.new("TextLabel")
spinLabel.Size = UDim2.new(0.24,0,0,18)
spinLabel.Position = UDim2.new(0.58,6,0,112)
spinLabel.BackgroundTransparency = 1
spinLabel.Text = "Spin"
spinLabel.Font = Enum.Font.Gotham
spinLabel.TextSize = 12
spinLabel.TextColor3 = Color3.fromRGB(200,200,200)
spinLabel.Parent = editFrame
local spinBox = Instance.new("TextBox")
spinBox.Size = UDim2.new(0.40,-10,0,18)
spinBox.Position = UDim2.new(0.82,-4,0,112)
spinBox.BackgroundColor3 = Color3.fromRGB(28,28,28)
spinBox.TextColor3 = Color3.fromRGB(240,240,240)
spinBox.Text = tostring(CustomStats.spin)
spinBox.Font = Enum.Font.Gotham
spinBox.TextSize = 12
spinBox.ClearTextOnFocus = false
spinBox.Parent = editFrame
local spinCorner = Instance.new("UICorner", spinBox)
spinCorner.CornerRadius = UDim.new(0,4)
gear.MouseButton1Click:Connect(function()
editFrame.Visible = not editFrame.Visible
end)
-- apply custom (update stats & button text)
local function applyCustom()
local nameText = tostring(nameBox.Text or ""):gsub("^%s*(.-)%s*$", "%1")
if nameText == "" then nameText = "Custom Fling" end
local f = tonumber(forceBox.Text) or CustomStats.force
local u = tonumber(upBox.Text) or CustomStats.up
local d = tonumber(durBox.Text) or CustomStats.dur
local s = tonumber(spinBox.Text) or CustomStats.spin
if f < 0 then f = 0 end
if u < 0 then u = 0 end
if d <= 0 then d = 0.05 end
if s < 0 then s = 0 end
CustomStats = {force = f, up = u, dur = d, spin = s}
customName = nameText
pcall(function() customBtn.Text = customName end)
end
local boxes = {nameBox, forceBox, upBox, durBox, spinBox}
for _,tb in ipairs(boxes) do
tb.FocusLost:Connect(function(enterPressed) if enterPressed then applyCustom() end end)
end
-- initial editor follow
pcall(updateEditPosition)
-- apply initial filter (show all)
filterButtons("")
-- if we created GUI while frozen, reflect freeze button text
if isFrozen then pcall(function() freezeBtn.Text = "Unfreeze ❄️" end) end
end
-- init
createFlingGui()
-- respawn handler
player.CharacterAdded:Connect(function(newChar)
character = newChar
humanoidRootPart = character:WaitForChild("HumanoidRootPart")
humanoid = character:WaitForChild("Humanoid")
-- ensure player not frozen on new character
isFrozen = false
pcall(function()
if humanoidRootPart then humanoidRootPart.Anchored = false end
if humanoid then humanoid.PlatformStand = false end
end)
-- small wait then attempt to recreate gui (createFlingGui respects the "FlingGuiClosed" attribute)
task.wait(0.12)
createFlingGui()
end)



Holy many YAPP I don't hate just saying no hate no noting just that but that much words or you have used chatgpt but I don't care
@nikitakalitin2 ok
Btw I frogot I was searching for this long time and never found one thanks
@nikitakalitin2 ok