![Plot Manager [DISCONTINUED]](https://scriptblox.com/images/sb/81505591700031-1785651452583.png)
Keyless

--// Auto Enchant GUI - Inventory Scan Method
--// Features:
--// 1) Multi-unit queue (cycles units list)
--// 2) Backup enchants when Dark Aura < Stop Amount
--// 3) GUI like mockup + debug log (also prints console)
--// 4) Fail-safe idle when Dark Aura is 0/unavailable
--//
--// Toggle: K
--// Unload: M (full unload)
--// GUI Scaling (1.0 = normal, 0.9 = 10% smaller, 0.8 = 20% smaller, etc.)
local UI_SCALE = 0.5
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local CoreGui = game:GetService("CoreGui")
--========================
-- CONFIG
--========================
local TOGGLE_KEY = Enum.KeyCode.K
local UNLOAD_KEY = Enum.KeyCode.M
-- Loop timing
local INVOKE_COOLDOWN = 0.45 -- time to wait after an enchant invoke (lets UI update)
local STEP_DELAY = 0.05 -- tiny delay between steps to keep things smooth
local IDLE_RECHECK = 1.0 -- how often to check while idling (no aura / all done)
-- Match confirmation (prevents “saw Fallen then rerolled it”)
local CONFIRM_TIME = 0.70
local CONFIRM_MATCHES = 3
local CONFIRM_SAMPLE_DELAY = 0.12
local DEBUG_DEFAULT = true
local MAX_LOG_LINES = 80
--========================
-- Singleton / Cleanup
--========================
local SINGLETON_KEY = "_AUTO_ENCHANT_FULL_V1"
local env = (getgenv and getgenv()) or _G
if env[SINGLETON_KEY] and type(env[SINGLETON_KEY]) == "function" then
pcall(env[SINGLETON_KEY])
end
local state = {
enabled = false,
loopToken = 0,
conns = {},
gui = nil,
manualPos = false,
debug = DEBUG_DEFAULT,
}
local function connect(sig, fn)
local c = sig:Connect(fn)
table.insert(state.conns, c)
return c
end
local function cleanup()
state.enabled = false
state.loopToken += 1
for _, c in ipairs(state.conns) do
pcall(function() c:Disconnect() end)
end
state.conns = {}
if state.gui then
pcall(function() state.gui:Destroy() end)
end
env[SINGLETON_KEY] = nil
print("[AutoEnchant] Unloaded.")
end
env[SINGLETON_KEY] = cleanup
--========================
-- Paths (your UI)
--========================
local player = Players.LocalPlayer
local main = player:WaitForChild("PlayerGui"):WaitForChild("Main")
local unitEnchantFrame = main:WaitForChild("UnitEnchant"):WaitForChild("MainFrame")
local unitInventory = main:WaitForChild("UnitInventory")
local inventoryFrame = unitInventory:WaitForChild("MainFrame"):WaitForChild("InventoryFrame")
local unitScroll = inventoryFrame:WaitForChild("UnitScrollingFrame")
local itemsScroll = inventoryFrame:WaitForChild("ItemsScrollingFrame")
local darkAuraLabel =
itemsScroll:WaitForChild("Dark Aura")
:WaitForChild("UnitAmount") -- "x24"
local enchantRemote = ReplicatedStorage:WaitForChild("EnchantUnit") -- RemoteFunction
--========================
-- Helpers
--========================
local function norm(s)
return tostring(s or ""):lower():gsub("^%s+", ""):gsub("%s+$", "")
end
local function splitList(text)
-- supports commas and newlines
local out = {}
text = tostring(text or "")
text = text:gsub("\r", "\n")
text = text:gsub(",", "\n")
for line in text:gmatch("[^\n]+") do
local v = line:gsub("^%s+", ""):gsub("%s+$", "")
if v ~= "" then table.insert(out, v) end
end
return out
end
local function parseXAmount(txt)
-- "x24" -> 24
txt = tostring(txt or ""):gsub(",", "")
local n = txt:match("^x(%d+)$") or txt:match("x(%d+)")
return tonumber(n) or 0
end
local function getDarkAura()
return parseXAmount(darkAuraLabel.Text)
end
local function enchantTextToValue(txt)
-- "Enchant Label" == no enchant
if not txt then return nil end
local t = tostring(txt):gsub("^%s+", ""):gsub("%s+$", "")
if t == "" then return nil end
if t == "Enchant Label" then return nil end
return t
end
local function anyMatches(current, list)
local cur = norm(current)
for _, v in ipairs(list or {}) do
if cur == norm(v) then return true, v end
end
return false, nil
end
local function unionLists(a, b)
local out = {}
for _, v in ipairs(a or {}) do table.insert(out, v) end
for _, v in ipairs(b or {}) do table.insert(out, v) end
return out
end
-- Find enchant TextLabel inside a unit container (descendant scan)
local function findEnchantLabel(unitContainer)
for _, d in ipairs(unitContainer:GetDescendants()) do
if d.Name == "Enchant" and d:IsA("TextLabel") then
return d
end
end
return nil
end
local function getUnitEnchant(unitName)
local unitContainer = unitScroll:FindFirstChild(unitName)
if not unitContainer then
return nil, "MISSING"
end
local lbl = findEnchantLabel(unitContainer)
if not lbl then
return nil, "NO_LABEL"
end
return enchantTextToValue(lbl.Text), "OK"
end
local function confirmTarget(unitName, acceptedTargets)
local matches = 0
local t0 = os.clock()
while os.clock() - t0 < CONFIRM_TIME do
local cur, status = getUnitEnchant(unitName)
if status == "MISSING" then
return false, "MISSING"
end
if cur then
local ok = anyMatches(cur, acceptedTargets)
if ok then
matches += 1
if matches >= CONFIRM_MATCHES then
return true, cur
end
end
end
task.wait(CONFIRM_SAMPLE_DELAY)
end
return false, "NOT_STABLE"
end
--========================
-- GUI (mockup style + debug log)
--========================
local gui = Instance.new("ScreenGui")
gui.Name = "AutoEnchantGUI"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.Parent = player:FindFirstChild("PlayerGui") or CoreGui
state.gui = gui
local panel = Instance.new("Frame")
panel.Size = UDim2.fromOffset(1080, 420) -- base size (unscaled)
panel.BackgroundColor3 = Color3.fromRGB(10,10,10)
panel.BorderSizePixel = 0
panel.Active = true
panel.Parent = gui
Instance.new("UICorner", panel).CornerRadius = UDim.new(0, 26)
-- >>> ADD THIS (group-scale everything like Adobe Express)
local scaler = Instance.new("UIScale")
scaler.Name = "PanelScaler"
scaler.Scale = UI_SCALE
scaler.Parent = panel
local border = Instance.new("UIStroke", panel)
border.Thickness = 6
border.Color = Color3.fromRGB(255, 90, 80)
local title = Instance.new("TextLabel")
title.BackgroundTransparency = 1
title.Size = UDim2.new(1, -30, 0, 40)
title.Position = UDim2.fromOffset(15, 10)
title.Font = Enum.Font.GothamMedium
title.TextSize = 22
title.TextColor3 = Color3.fromRGB(220,220,220)
title.Text = "Auto Enchant GUI - Inventory Scan Method"
title.TextXAlignment = Enum.TextXAlignment.Center
title.Parent = panel
local function mkBox(y, h, placeholder)
local tb = Instance.new("TextBox")
tb.Size = UDim2.new(1, -60, 0, h)
tb.Position = UDim2.fromOffset(30, y)
tb.BackgroundColor3 = Color3.fromRGB(85,85,85)
tb.TextColor3 = Color3.fromRGB(235,235,235)
tb.PlaceholderColor3 = Color3.fromRGB(210,210,210)
tb.PlaceholderText = placeholder
tb.ClearTextOnFocus = false
tb.Font = Enum.Font.Gotham
tb.TextSize = 16
tb.TextWrapped = true
tb.Text = ""
tb.Parent = panel
Instance.new("UICorner", tb).CornerRadius = UDim.new(0, 14)
return tb
end
local unitsBox = mkBox(60, 54, "Units to enchant. (comma or newline separated)")
unitsBox.Text = "Frost Queen, Moon Watcher, Golden Signal"
local leftBox = Instance.new("TextBox")
leftBox.Size = UDim2.new(0.5, -40, 0, 46)
leftBox.Position = UDim2.fromOffset(30, 122)
leftBox.BackgroundColor3 = Color3.fromRGB(85,85,85)
leftBox.TextColor3 = Color3.fromRGB(235,235,235)
leftBox.PlaceholderText = "Dark Aura Stop Amount:"
leftBox.ClearTextOnFocus = false
leftBox.Font = Enum.Font.Gotham
leftBox.TextSize = 16
leftBox.Text = "25"
leftBox.Parent = panel
Instance.new("UICorner", leftBox).CornerRadius = UDim.new(0, 14)
local backupBox = Instance.new("TextBox")
backupBox.Size = UDim2.new(0.5, -40, 0, 46)
backupBox.Position = UDim2.fromOffset(30 + (panel.Size.X.Offset/2), 122) -- right side
backupBox.BackgroundColor3 = Color3.fromRGB(85,85,85)
backupBox.TextColor3 = Color3.fromRGB(235,235,235)
backupBox.PlaceholderText = "Enchant Backups. (comma/newline)"
backupBox.ClearTextOnFocus = false
backupBox.Font = Enum.Font.Gotham
backupBox.TextSize = 16
backupBox.Text = "Damage, Range, Speed"
backupBox.Parent = panel
Instance.new("UICorner", backupBox).CornerRadius = UDim.new(0, 14)
local mainEnchantsBox = mkBox(178, 54, "Main Enchants (comma/newline)")
mainEnchantsBox.Text = "Golden, Fallen"
local toggleBtn = Instance.new("TextButton")
toggleBtn.Size = UDim2.new(1, -60, 0, 68)
toggleBtn.Position = UDim2.fromOffset(30, 238)
toggleBtn.BackgroundColor3 = Color3.fromRGB(190, 0, 0)
toggleBtn.TextColor3 = Color3.fromRGB(255,255,255)
toggleBtn.Font = Enum.Font.GothamBlack
toggleBtn.TextSize = 44
toggleBtn.Text = "Auto Enchant OFF."
toggleBtn.Parent = panel
Instance.new("UICorner", toggleBtn).CornerRadius = UDim.new(0, 16)
local logBox = Instance.new("TextBox")
logBox.Size = UDim2.new(1, -60, 0, 70)
logBox.Position = UDim2.fromOffset(30, 312)
logBox.BackgroundColor3 = Color3.fromRGB(20,20,20)
logBox.TextColor3 = Color3.fromRGB(210,210,210)
logBox.Font = Enum.Font.Code
logBox.TextSize = 12
logBox.TextXAlignment = Enum.TextXAlignment.Left
logBox.TextYAlignment = Enum.TextYAlignment.Top
logBox.ClearTextOnFocus = false
logBox.TextEditable = false
logBox.MultiLine = true
logBox.Text = ""
logBox.Parent = panel
Instance.new("UICorner", logBox).CornerRadius = UDim.new(0, 10)
local logPad = Instance.new("UIPadding", logBox)
logPad.PaddingLeft = UDim.new(0, 8)
logPad.PaddingTop = UDim.new(0, 6)
logPad.PaddingRight = UDim.new(0, 8)
logPad.PaddingBottom = UDim.new(0, 6)
local logLines = {}
local function log(msg)
local line = ("[%s] %s"):format(os.date("%H:%M:%S"), tostring(msg))
table.insert(logLines, line)
if #logLines > MAX_LOG_LINES then
table.remove(logLines, 1)
end
logBox.Text = table.concat(logLines, "\n")
logBox.CursorPosition = #logBox.Text + 1
print("[AutoEnchant]", msg)
end
local function setEnabled(on)
state.enabled = on
if on then
toggleBtn.BackgroundColor3 = Color3.fromRGB(0, 150, 70)
toggleBtn.Text = "Auto Enchant ON."
else
toggleBtn.BackgroundColor3 = Color3.fromRGB(190, 0, 0)
toggleBtn.Text = "Auto Enchant OFF."
end
end
-- draggable + auto-anchor under enchant UI until dragged
do
local dragging = false
local dragStart, startPos
connect(panel.InputBegan, function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
state.manualPos = true
dragStart = input.Position
startPos = panel.Position
end
end)
connect(UserInputService.InputChanged, function(input)
if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
local delta = input.Position - dragStart
panel.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
end)
connect(UserInputService.InputEnded, function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end)
end
-- show only when enchant UI open, and auto-place if not manually moved
connect(RunService.RenderStepped, function()
panel.Visible = unitEnchantFrame.Visible
if not panel.Visible then return end
if not state.manualPos then
local p, s = unitEnchantFrame.AbsolutePosition, unitEnchantFrame.AbsoluteSize
panel.Position = UDim2.fromOffset(p.X - 10, p.Y + s.Y + 16)
end
end)
--========================
-- Main loop
--========================
local function getStopAmount()
local n = tonumber(leftBox.Text)
if not n then return 0 end
if n < 0 then n = 0 end
return n
end
local function getLists()
local units = splitList(unitsBox.Text)
local mainTargets = splitList(mainEnchantsBox.Text)
local backups = splitList(backupBox.Text)
return units, mainTargets, backups
end
local function getAcceptedTargets(aura, stopAmt, mainTargets, backups)
if aura < stopAmt then
return unionLists(mainTargets, backups), "BACKUP MODE"
end
return mainTargets, "MAIN MODE"
end
local function allUnitsSatisfied(units, acceptedTargets)
for _, u in ipairs(units) do
local cur, status = getUnitEnchant(u)
if status == "MISSING" then
-- missing units are ignored (not a failure)
else
local ok = false
if cur then ok = anyMatches(cur, acceptedTargets) end
if not ok then return false end
end
end
return true
end
local function startLoop()
state.loopToken += 1
local myToken = state.loopToken
task.spawn(function()
log("Loop started. (K toggle, M unload)")
while state.enabled and state.loopToken == myToken do
-- If enchant UI closed, just wait (keeps enabled)
if not unitEnchantFrame.Visible then
log("Enchant UI closed -> waiting...")
task.wait(IDLE_RECHECK)
continue
end
local units, mainTargets, backups = getLists()
if #units == 0 then
log("No units listed. Add units to enchant.")
task.wait(IDLE_RECHECK)
continue
end
if #mainTargets == 0 and #backups == 0 then
log("No enchants listed. Add main/backups.")
task.wait(IDLE_RECHECK)
continue
end
local aura = getDarkAura()
local stopAmt = getStopAmount()
if aura <= 0 then
log(("Dark Aura=%d -> idle until it returns..."):format(aura))
task.wait(IDLE_RECHECK)
continue
end
local acceptedTargets, mode = getAcceptedTargets(aura, stopAmt, mainTargets, backups)
log(("Mode=%s | DarkAura=%d | Stop=%d | Units=%d"):format(mode, aura, stopAmt, #units))
-- If everyone already has an accepted enchant, idle but stay enabled
if allUnitsSatisfied(units, acceptedTargets) then
log("All listed units already match accepted enchants -> standing by...")
task.wait(IDLE_RECHECK)
continue
end
-- Cycle units
for _, unitName in ipairs(units) do
if not (state.enabled and state.loopToken == myToken) then break end
local cur, status = getUnitEnchant(unitName)
if status == "MISSING" then
log(("Unit '%s' missing from UnitScrollingFrame -> skipping"):format(unitName))
task.wait(STEP_DELAY)
continue
end
if cur then
local ok = anyMatches(cur, acceptedTargets)
if ok then
log(("%s already good: %s -> next unit"):format(unitName, cur))
task.wait(STEP_DELAY)
continue
else
log(("%s current=%s (not accepted) -> rolling..."):format(unitName, cur))
end
else
log(("%s current=(none) -> rolling..."):format(unitName))
end
-- Invoke enchant
local ok, res = pcall(function()
return enchantRemote:InvokeServer(unitName)
end)
if not ok then
log(("Invoke error on %s: %s"):format(unitName, tostring(res)))
task.wait(0.8)
continue
end
-- Let UI update
task.wait(INVOKE_COOLDOWN)
-- Re-check + confirm if hit
local after, _ = getUnitEnchant(unitName)
if after then
local hit = anyMatches(after, acceptedTargets)
if hit then
log(("%s saw target '%s' -> confirming..."):format(unitName, after))
local confirmed, final = confirmTarget(unitName, acceptedTargets)
if confirmed then
log(("%s confirmed '%s' -> locking it in, moving on"):format(unitName, final))
else
log(("%s match not stable yet -> continuing later"):format(unitName))
end
else
log(("%s rolled -> now=%s"):format(unitName, after))
end
else
log(("%s rolled -> still shows (none)"):format(unitName))
end
task.wait(STEP_DELAY)
end
end
log("Loop exited.")
end)
end
--========================
-- Controls
--========================
connect(toggleBtn.MouseButton1Click, function()
setEnabled(not state.enabled)
if state.enabled then
startLoop()
else
log("Toggled OFF.")
end
end)
connect(UserInputService.InputBegan, function(input, gp)
if gp then return end
if input.KeyCode == TOGGLE_KEY then
setEnabled(not state.enabled)
if state.enabled then
startLoop()
else
log("Toggled OFF.")
end
elseif input.KeyCode == UNLOAD_KEY then
cleanup()
end
end)
-- Init
setEnabled(false)
log("Ready. Enter units + enchants. Toggle with K. Unload with M.")
Wow
jehe