
Funky Duels Script Kasana: Auto Play, Stat Spoofer
0 views

Use this Kasana hub for Funky Duels Roblox!! Now you can get features like Perfect Hit Mode, Suppress Misses, Auto Play, Live HUD Spoof and Stat Spoofer, and More!! Every switch in the window starts on, split into Network Replication, Autoplay Controls and Data Spoofer sections. Hit Mode stays on Perfect while its switch is on, and turning it off plays in a legit style instead, while Auto Release Holds lets go of long notes for you. The whole script is posted as open source, so you can read every line before running it. No key on this one, so paste the loadstring and go!!
Explore more scripts for this game (1)
-- Developed for my sempai:33333333333
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local PlayerScripts = LocalPlayer:WaitForChild("PlayerScripts")
local Client = PlayerScripts:WaitForChild("Client")
local Gameplay = Client:WaitForChild("Gameplay")
local UI = Client:WaitForChild("UI")
local Note = require(Gameplay:WaitForChild("Note"))
local Input = require(Gameplay:WaitForChild("Input"))
local Hud = require(Gameplay:WaitForChild("Hud"))
local State = require(Client:WaitForChild("Core"):WaitForChild("State"))
local Results = require(UI:WaitForChild("Screens"):WaitForChild("Results"))
local Round = require(Gameplay:WaitForChild("Round"))
if _G.FunkyDuelsCleanup then
pcall(_G.FunkyDuelsCleanup)
end
local Config = {
Autoplay = true,
HitMode = "Perfect",
LegitJitter = 12,
AutoHold = true,
ServerReplication = true,
PreventMisses = true,
SpoofEnabled = true,
LiveHudSpoof = true,
ResultsSpoof = true,
Score = 1500000,
Misses = 0,
Accuracy = 100.0,
Sicks = 999,
Goods = 0,
Okays = 0,
Bads = 0,
Combo = 999,
MaxCombo = 999
}
local activeHolds = {}
local handledNotes = {}
local connections = {}
local originalMethods = {}
local rawTryHitNote = Note.TryHitNote
local rawGetResults = Note.GetResults
local rawApplyGhostMiss = Note.ApplyGhostMiss
local rawSetNoteResolvedCallback = Note.SetNoteResolvedCallback
local function sanitizeInt(val, defaultVal, maxVal)
local n = tonumber(val) or (defaultVal or 0)
if n ~= n or n == math.huge or n == -math.huge then
n = defaultVal or 0
end
return math.clamp(math.floor(n), 0, maxVal or 999999999)
end
local function sanitizeFloat(val, defaultVal, minVal, maxVal)
local n = tonumber(val) or (defaultVal or 0)
if n ~= n or n == math.huge or n == -math.huge then
n = defaultVal or 0
end
return math.clamp(n, minVal or 0, maxVal or 100)
end
local function getInputHandlers()
local upvals = debug.getupvalues(Input.Init)
local bindKb = upvals[8]
if bindKb then
local inner = debug.getupvalues(bindKb)
return inner[5], inner[6]
end
return nil, nil
end
local function getNoteContext()
local upvals = debug.getupvalues(rawTryHitNote)
return {
conductor = upvals[1],
timingOffset = upvals[2] or 0,
noteList = upvals[3],
roundContext = upvals[4],
match = upvals[5],
hitNote = upvals[7]
}
end
local function isLocalNote(note, context)
if not context or not context.SessionLocalSide then
return note.IsPlayer == true
end
return (note.IsPlayer == false) == (context.SessionLocalSide == "Left")
end
local showStats = debug.getupvalues(Results.Show)[1]
local origSetCount = debug.getupvalues(showStats)[2]
local u63 = debug.getupvalues(origSetCount)[1]
local function safeSetCount(frame, count)
if not frame or not frame:FindFirstChild("Index") then return end
local Index = frame.Index
for _, c in ipairs(frame:GetChildren()) do
if c ~= Index and not c:IsA("UIListLayout") then
c:Destroy()
end
end
Index.Visible = false
local num = sanitizeInt(count, 0, 999999999)
local str = string.format("%d", num)
for i = 1, #str do
local digit = tonumber(str:sub(i, i))
if digit and u63[digit + 1] and u63[digit + 1][1] then
local clone = Index:Clone()
clone.LayoutOrder = i
clone.Visible = true
clone.Image = u63[digit + 1][1].assetId
clone.Parent = frame
end
end
end
debug.setupvalue(showStats, 2, safeSetCount)
debug.setupvalue(Results.Show, 3, safeSetCount)
originalMethods.SetNoteResolvedCallback = rawSetNoteResolvedCallback
Note.SetNoteResolvedCallback = function(callback)
local wrappedCallback = function(target, count, isHit, dir, noteData)
if target == "player" and Config.SpoofEnabled and Config.ServerReplication then
if noteData then
noteData.ResolvedSongTimeMs = noteData.TimeMs
end
if Config.PreventMisses then
isHit = true
end
end
return callback(target, count, isHit, dir, noteData)
end
return rawSetNoteResolvedCallback(wrappedCallback)
end
originalMethods.ApplyGhostMiss = rawApplyGhostMiss
Note.ApplyGhostMiss = function(dir)
if Config.SpoofEnabled and Config.PreventMisses then
return false
end
return rawApplyGhostMiss(dir)
end
local function syncInternalStats()
if not Config.SpoofEnabled then return end
local upvals = debug.getupvalues(rawGetResults)
if not upvals or #upvals < 8 then return end
if type(upvals[5]) == "table" then
upvals[5].SICK = sanitizeInt(Config.Sicks, 999)
upvals[5].GOOD = sanitizeInt(Config.Goods, 0)
upvals[5].OKAY = sanitizeInt(Config.Okays, 0)
upvals[5].BAD = sanitizeInt(Config.Bads, 0)
end
if type(upvals[2]) == "table" then
upvals[2].score = sanitizeInt(Config.Score, 1500000)
upvals[2].misses = sanitizeInt(Config.Misses, 0)
upvals[2].accuracy = sanitizeFloat(Config.Accuracy, 100, 0, 100)
upvals[2].combo = sanitizeInt(Config.MaxCombo, 999)
upvals[2].maxCombo = sanitizeInt(Config.MaxCombo, 999)
end
debug.setupvalue(rawGetResults, 6, sanitizeInt(Config.MaxCombo, 999))
debug.setupvalue(rawGetResults, 7, sanitizeInt(Config.Misses, 0))
debug.setupvalue(rawGetResults, 8, sanitizeInt(Config.Score, 1500000))
end
originalMethods.GetResults = rawGetResults
Note.GetResults = function(...)
syncInternalStats()
local res = rawGetResults(...)
if Config.SpoofEnabled and type(res) == "table" then
res.score = sanitizeInt(Config.Score, res.score or 0)
res.misses = sanitizeInt(Config.Misses, res.misses or 0)
res.accuracy = sanitizeFloat(Config.Accuracy, res.accuracy or 100, 0, 100)
res.sicks = sanitizeInt(Config.Sicks, res.sicks or 0)
res.goods = sanitizeInt(Config.Goods, res.goods or 0)
res.okays = sanitizeInt(Config.Okays, res.okays or 0)
res.bads = sanitizeInt(Config.Bads, res.bads or 0)
res.maxCombo = sanitizeInt(Config.MaxCombo, res.maxCombo or 0)
end
return res
end
originalMethods.RenderStats = Hud.RenderStats
Hud.RenderStats = function(score, misses, accuracy, combo)
if Config.SpoofEnabled and Config.LiveHudSpoof then
score = sanitizeInt(Config.Score, score or 0)
misses = sanitizeInt(Config.Misses, misses or 0)
accuracy = sanitizeFloat(Config.Accuracy, accuracy or 100, 0, 100)
combo = sanitizeInt(Config.Combo, combo or 0)
end
return originalMethods.RenderStats(score, misses, accuracy, combo)
end
originalMethods.Show = Results.Show
Results.Show = function(pStats, songName, diff, oppStats, isSolo)
if Config.SpoofEnabled and Config.ResultsSpoof and type(pStats) == "table" then
pStats.score = sanitizeInt(Config.Score, pStats.score or 0)
pStats.misses = sanitizeInt(Config.Misses, pStats.misses or 0)
pStats.accuracy = sanitizeFloat(Config.Accuracy, pStats.accuracy or 100, 0, 100)
pStats.sicks = sanitizeInt(Config.Sicks, pStats.sicks or 0)
pStats.goods = sanitizeInt(Config.Goods, pStats.goods or 0)
pStats.okays = sanitizeInt(Config.Okays, pStats.okays or 0)
pStats.bads = sanitizeInt(Config.Bads, pStats.bads or 0)
pStats.maxCombo = sanitizeInt(Config.MaxCombo, pStats.maxCombo or 0)
end
if type(oppStats) == "table" then
oppStats.sicks = sanitizeInt(oppStats.sicks, 0)
oppStats.goods = sanitizeInt(oppStats.goods, 0)
oppStats.okays = sanitizeInt(oppStats.okays, 0)
oppStats.bads = sanitizeInt(oppStats.bads, 0)
oppStats.maxCombo = sanitizeInt(oppStats.maxCombo, 0)
oppStats.misses = sanitizeInt(oppStats.misses, 0)
end
local success, err = pcall(function()
originalMethods.Show(pStats, songName, diff, oppStats, isSolo)
end)
if not success then
pcall(function()
local up = debug.getupvalues(originalMethods.Show)
if up[13] then up[13].Visible = true end
end)
end
end
local onSongEnded = debug.getupvalues(Round.StartRound)[35]
local songEndWatchdogTriggered = false
local lastActiveNoteTime = 0
local function checkSongEndWatchdog(liveSongTime, noteList, roundContext)
if songEndWatchdogTriggered then return end
if Results.IsVisible() then return end
if not roundContext or roundContext.RoundOver then return end
local hasUnresolvedNotes = false
local maxTime = 0
for _, n in ipairs(noteList) do
if not n.Hit and not n.Missed then
hasUnresolvedNotes = true
end
if n.TimeMs and n.TimeMs > maxTime then
maxTime = n.TimeMs
end
end
if maxTime > 0 then
lastActiveNoteTime = maxTime
end
if not hasUnresolvedNotes and lastActiveNoteTime > 0 and liveSongTime >= lastActiveNoteTime + 2500 then
songEndWatchdogTriggered = true
task.defer(function()
if onSongEnded and not Results.IsVisible() and not roundContext.RoundOver then
pcall(onSongEnded)
end
end)
end
end
local function onHeartbeat()
if State.GetState() ~= "InGame" then
table.clear(activeHolds)
table.clear(handledNotes)
songEndWatchdogTriggered = false
lastActiveNoteTime = 0
return
end
local ctx = getNoteContext()
if not ctx.conductor or type(ctx.conductor.GetLiveSongTimeMs) ~= "function" or not ctx.noteList or not ctx.roundContext then return end
if ctx.roundContext.RoundOver or Note.IsPaused() then return end
syncInternalStats()
local hp, hr = getInputHandlers()
local liveSongTime = ctx.conductor.GetLiveSongTimeMs() + ctx.timingOffset
checkSongEndWatchdog(liveSongTime, ctx.noteList, ctx.roundContext)
if not Config.Autoplay then return end
if Config.AutoHold then
for dir, hold in pairs(activeHolds) do
if liveSongTime >= hold.endTime - 8 then
if hr then hr(dir) end
activeHolds[dir] = nil
end
end
end
for _, note in ipairs(ctx.noteList) do
if not note.Hit and not note.Missed and not handledNotes[note] then
if isLocalNote(note, ctx.roundContext) then
local jitter = 0
if Config.HitMode == "Legit" then
if not note._jitter then
note._jitter = math.random(-Config.LegitJitter, Config.LegitJitter)
end
jitter = note._jitter
end
local targetHitTime = note.TimeMs + jitter
if liveSongTime >= targetHitTime then
handledNotes[note] = true
if Config.ServerReplication then
note.ResolvedSongTimeMs = note.TimeMs
end
if hp then hp(note.Dir) end
if not note.Hit then rawTryHitNote(note.Dir) end
if note.HoldMs and note.HoldMs > 0 then
activeHolds[note.Dir] = {
dir = note.Dir,
endTime = note.TimeMs + note.HoldMs
}
else
task.delay(0.045 + math.random() * 0.015, function()
if hr and not activeHolds[note.Dir] then
hr(note.Dir)
end
end)
end
end
end
end
end
if #ctx.noteList == 0 and next(handledNotes) ~= nil then
table.clear(handledNotes)
end
end
table.insert(connections, RunService.Heartbeat:Connect(onHeartbeat))
local targetParent = (gethui and gethui()) or game:GetService("CoreGui"):FindFirstChild("RobloxGui") or LocalPlayer:WaitForChild("PlayerGui")
local gui = Instance.new("ScreenGui")
gui.Name = "FunkyDuels_Mod"
gui.ResetOnSpawn = false
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
local mainFrame = Instance.new("Frame")
mainFrame.Name = "MainFrame"
mainFrame.Size = UDim2.new(0, 300, 0, 380)
mainFrame.Position = UDim2.new(0.5, -150, 0.5, -190)
mainFrame.BackgroundColor3 = Color3.fromRGB(14, 12, 20)
mainFrame.BorderSizePixel = 0
mainFrame.Active = true
mainFrame.Draggable = true
mainFrame.ClipsDescendants = true
mainFrame.Parent = gui
local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 8)
mainCorner.Parent = mainFrame
local mainStroke = Instance.new("UIStroke")
mainStroke.Color = Color3.fromRGB(145, 65, 235)
mainStroke.Thickness = 1.2
mainStroke.Parent = mainFrame
local titleBar = Instance.new("Frame")
titleBar.Size = UDim2.new(1, 0, 0, 32)
titleBar.BackgroundColor3 = Color3.fromRGB(22, 18, 32)
titleBar.BorderSizePixel = 0
titleBar.Parent = mainFrame
local titleCorner = Instance.new("UICorner")
titleCorner.CornerRadius = UDim.new(0, 8)
titleCorner.Parent = titleBar
local titleFix = Instance.new("Frame")
titleFix.Size = UDim2.new(1, 0, 0, 8)
titleFix.Position = UDim2.new(0, 0, 1, -8)
titleFix.BackgroundColor3 = Color3.fromRGB(22, 18, 32)
titleFix.BorderSizePixel = 0
titleFix.Parent = titleBar
local titleText = Instance.new("TextLabel")
titleText.Size = UDim2.new(1, -64, 1, 0)
titleText.Position = UDim2.new(0, 10, 0, 0)
titleText.Text = "funky duels script"
titleText.Font = Enum.Font.GothamBold
titleText.TextSize = 12
titleText.TextColor3 = Color3.fromRGB(195, 130, 255)
titleText.TextXAlignment = Enum.TextXAlignment.Left
titleText.BackgroundTransparency = 1
titleText.Parent = titleBar
local minBtn = Instance.new("TextButton")
minBtn.Size = UDim2.new(0, 22, 0, 22)
minBtn.Position = UDim2.new(1, -50, 0.5, -11)
minBtn.Text = "-"
minBtn.Font = Enum.Font.GothamBold
minBtn.TextSize = 14
minBtn.TextColor3 = Color3.fromRGB(210, 190, 230)
minBtn.BackgroundColor3 = Color3.fromRGB(32, 26, 45)
minBtn.BorderSizePixel = 0
minBtn.AutoButtonColor = true
minBtn.Parent = titleBar
local minCorner = Instance.new("UICorner")
minCorner.CornerRadius = UDim.new(0, 4)
minCorner.Parent = minBtn
local closeBtn = Instance.new("TextButton")
closeBtn.Size = UDim2.new(0, 22, 0, 22)
closeBtn.Position = UDim2.new(1, -26, 0.5, -11)
closeBtn.Text = "X"
closeBtn.Font = Enum.Font.GothamBold
closeBtn.TextSize = 11
closeBtn.TextColor3 = Color3.fromRGB(255, 90, 90)
closeBtn.BackgroundColor3 = Color3.fromRGB(38, 20, 30)
closeBtn.BorderSizePixel = 0
closeBtn.AutoButtonColor = true
closeBtn.Parent = titleBar
local closeCorner = Instance.new("UICorner")
closeCorner.CornerRadius = UDim.new(0, 4)
closeCorner.Parent = closeBtn
local floatIcon = Instance.new("TextButton")
floatIcon.Name = "FloatingIcon"
floatIcon.Size = UDim2.new(0, 36, 0, 36)
floatIcon.Position = UDim2.new(0, 18, 0.5, -18)
floatIcon.BackgroundColor3 = Color3.fromRGB(14, 12, 20)
floatIcon.BorderSizePixel = 0
floatIcon.Text = "FD"
floatIcon.Font = Enum.Font.GothamBold
floatIcon.TextSize = 13
floatIcon.TextColor3 = Color3.fromRGB(195, 130, 255)
floatIcon.Active = true
floatIcon.Draggable = true
floatIcon.Visible = false
floatIcon.Parent = gui
local iconCorner = Instance.new("UICorner")
iconCorner.CornerRadius = UDim.new(0, 8)
iconCorner.Parent = floatIcon
local iconStroke = Instance.new("UIStroke")
iconStroke.Color = Color3.fromRGB(145, 65, 235)
iconStroke.Thickness = 1.2
iconStroke.Parent = floatIcon
local function showMain()
mainFrame.Visible = true
floatIcon.Visible = false
end
local function minimizeToIcon()
mainFrame.Visible = false
floatIcon.Visible = true
end
local function toggleGui()
if mainFrame.Visible then
minimizeToIcon()
else
showMain()
end
end
minBtn.MouseButton1Click:Connect(minimizeToIcon)
closeBtn.MouseButton1Click:Connect(minimizeToIcon)
floatIcon.MouseButton1Click:Connect(showMain)
table.insert(connections, UserInputService.InputBegan:Connect(function(input, gpe)
if not gpe and input.KeyCode == Enum.KeyCode.RightShift then
toggleGui()
end
end))
local content = Instance.new("ScrollingFrame")
content.Size = UDim2.new(1, -16, 1, -42)
content.Position = UDim2.new(0, 8, 0, 36)
content.BackgroundTransparency = 1
content.BorderSizePixel = 0
content.ScrollBarThickness = 3
content.ScrollBarImageColor3 = Color3.fromRGB(145, 65, 235)
content.CanvasSize = UDim2.new(0, 0, 0, 440)
content.Parent = mainFrame
local layout = Instance.new("UIListLayout")
layout.Padding = UDim.new(0, 5)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = content
local function createSection(text)
local sec = Instance.new("TextLabel")
sec.Size = UDim2.new(1, 0, 0, 20)
sec.Text = string.upper(text)
sec.Font = Enum.Font.GothamBold
sec.TextSize = 10
sec.TextColor3 = Color3.fromRGB(160, 130, 195)
sec.TextXAlignment = Enum.TextXAlignment.Left
sec.BackgroundTransparency = 1
sec.Parent = content
end
local function createToggle(label, initialVal, callback)
local btn = Instance.new("TextButton")
btn.Size = UDim2.new(1, 0, 0, 26)
btn.BackgroundColor3 = Color3.fromRGB(24, 20, 34)
btn.BorderSizePixel = 0
btn.AutoButtonColor = false
btn.Text = ""
btn.Parent = content
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 5)
btnCorner.Parent = btn
local txt = Instance.new("TextLabel")
txt.Size = UDim2.new(1, -50, 1, 0)
txt.Position = UDim2.new(0, 8, 0, 0)
txt.Text = label
txt.Font = Enum.Font.GothamMedium
txt.TextSize = 11
txt.TextColor3 = Color3.fromRGB(210, 220, 235)
txt.TextXAlignment = Enum.TextXAlignment.Left
txt.BackgroundTransparency = 1
txt.Parent = btn
local indicator = Instance.new("Frame")
indicator.Size = UDim2.new(0, 32, 0, 16)
indicator.Position = UDim2.new(1, -40, 0.5, -8)
indicator.BackgroundColor3 = initialVal and Color3.fromRGB(145, 65, 235) or Color3.fromRGB(45, 38, 55)
indicator.BorderSizePixel = 0
indicator.Parent = btn
local indCorner = Instance.new("UICorner")
indCorner.CornerRadius = UDim.new(1, 0)
indCorner.Parent = indicator
local dot = Instance.new("Frame")
dot.Size = UDim2.new(0, 12, 0, 12)
dot.Position = initialVal and UDim2.new(1, -14, 0.5, -6) or UDim2.new(0, 2, 0.5, -6)
dot.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
dot.BorderSizePixel = 0
dot.Parent = indicator
local dotCorner = Instance.new("UICorner")
dotCorner.CornerRadius = UDim.new(1, 0)
dotCorner.Parent = dot
local state = initialVal
btn.MouseButton1Click:Connect(function()
state = not state
indicator.BackgroundColor3 = state and Color3.fromRGB(145, 65, 235) or Color3.fromRGB(45, 38, 55)
dot.Position = state and UDim2.new(1, -14, 0.5, -6) or UDim2.new(0, 2, 0.5, -6)
callback(state)
end)
return btn
end
local function createInput(label, defaultVal, callback)
local frame = Instance.new("Frame")
frame.Size = UDim2.new(1, 0, 0, 26)
frame.BackgroundColor3 = Color3.fromRGB(24, 20, 34)
frame.BorderSizePixel = 0
frame.Parent = content
local fCorner = Instance.new("UICorner")
fCorner.CornerRadius = UDim.new(0, 5)
fCorner.Parent = frame
local txt = Instance.new("TextLabel")
txt.Size = UDim2.new(0.52, 0, 1, 0)
txt.Position = UDim2.new(0, 8, 0, 0)
txt.Text = label
txt.Font = Enum.Font.GothamMedium
txt.TextSize = 11
txt.TextColor3 = Color3.fromRGB(190, 205, 225)
txt.TextXAlignment = Enum.TextXAlignment.Left
txt.BackgroundTransparency = 1
txt.Parent = frame
local box = Instance.new("TextBox")
box.Size = UDim2.new(0.44, -8, 0, 20)
box.Position = UDim2.new(0.54, 0, 0.5, -10)
box.BackgroundColor3 = Color3.fromRGB(13, 11, 18)
box.BorderSizePixel = 0
box.Text = tostring(defaultVal)
box.Font = Enum.Font.GothamBold
box.TextSize = 11
box.TextColor3 = Color3.fromRGB(210, 150, 255)
box.ClearTextOnFocus = false
box.Parent = frame
local bCorner = Instance.new("UICorner")
bCorner.CornerRadius = UDim.new(0, 4)
bCorner.Parent = box
box.FocusLost:Connect(function()
callback(box.Text)
end)
return box
end
createSection("--- NETWORK REPLICATION ---")
createToggle("Server Replicate SICKs (0ms)", Config.ServerReplication, function(val) Config.ServerReplication = val end)
createToggle("Network Suppress Misses", Config.PreventMisses, function(val) Config.PreventMisses = val end)
createSection("--- AUTOPLAY CONTROLS ---")
createToggle("Autoplay Active", Config.Autoplay, function(val) Config.Autoplay = val end)
createToggle("Hit Mode: Perfect (OFF = Legit)", Config.HitMode == "Perfect", function(val)
Config.HitMode = val and "Perfect" or "Legit"
end)
createToggle("Auto Release Holds", Config.AutoHold, function(val) Config.AutoHold = val end)
createSection("--- DATA SPOOFER ---")
createToggle("Enable Data Spoofing", Config.SpoofEnabled, function(val) Config.SpoofEnabled = val end)
createToggle("Live HUD Display Spoof", Config.LiveHudSpoof, function(val) Config.LiveHudSpoof = val end)
createToggle("Results Screen Spoof", Config.ResultsSpoof, function(val) Config.ResultsSpoof = val end)
local boxScore = createInput("Spoofed Score", Config.Score, function(val) Config.Score = sanitizeInt(val, 1500000) end)
local boxAcc = createInput("Spoofed Accuracy %", Config.Accuracy, function(val) Config.Accuracy = sanitizeFloat(val, 100, 0, 100) end)
local boxSicks = createInput("Spoofed Sicks", Config.Sicks, function(val) Config.Sicks = sanitizeInt(val, 999) end)
local boxGoods = createInput("Spoofed Goods", Config.Goods, function(val) Config.Goods = sanitizeInt(val, 0) end)
local boxOkays = createInput("Spoofed Okays", Config.Okays, function(val) Config.Okays = sanitizeInt(val, 0) end)
local boxBads = createInput("Spoofed Bads", Config.Bads, function(val) Config.Bads = sanitizeInt(val, 0) end)
local boxMisses = createInput("Spoofed Misses", Config.Misses, function(val) Config.Misses = sanitizeInt(val, 0) end)
local boxCombo = createInput("Spoofed Max Combo", Config.MaxCombo, function(val)
Config.MaxCombo = sanitizeInt(val, 999)
Config.Combo = Config.MaxCombo
end)
_G.FunkyDuelsCleanup = function()
for _, conn in ipairs(connections) do
pcall(function() conn:Disconnect() end)
end
table.clear(connections)
Note.TryHitNote = rawTryHitNote
Note.GetResults = rawGetResults
Note.ApplyGhostMiss = rawApplyGhostMiss
Note.SetNoteResolvedCallback = rawSetNoteResolvedCallback
if originalMethods.RenderStats then Hud.RenderStats = originalMethods.RenderStats end
if originalMethods.Show then Results.Show = originalMethods.Show end
pcall(function()
debug.setupvalue(showStats, 2, origSetCount)
debug.setupvalue(Results.Show, 3, origSetCount)
end)
if gui and gui.Parent then
gui:Destroy()
end
_G.FunkyDuelsCleanup = nil
print("[FunkyDuels] V5 Unloaded cleanly.")
end
gui.Parent = targetParent
print("all vibecoders are femboys:333")