--[[ RUCK INSPECTOR AIO Version: 0.1.0 UI: WindUI 1.6.66 Features: - ESP labels for Mobs, Chests, Shrines, Camps, Resources, Pickups - Per-category toggle, max distance and type filter - Mob species detected from name (Cow_1 -> Cow, Goblin_10 -> Goblin) - Optional highlights (Roblox only renders 31 at once, so nearest 30) - Diagnostics: type census, folder inspection, nearest object inspector - Single-instance guard (re-executing replaces the old copy) - RightShift / RightControl window toggle Target: Roblox Player ]] --================================================== -- INITIALIZATION --================================================== local VERSION = "0.1.0" local WINDUI_VERSION = "1.6.66" local startedAt = os.clock() local WindUI = nil local Window = nil local Container = nil local Connections = {} local Entries = {} -- [instance] = entry local CONTAINER_NAME = "RuckInspectorVisuals" local CONFIG = { Version = VERSION, WindUIVersion = WINDUI_VERSION, MaxLogs = 60, Notifications = true, } local Settings = { Highlights = false, MaxHighlights = 30, ShowDistance = true, ShowHealth = true, ScanInterval = 1.5, } local State = { Running = true, Logs = {}, TotalCreated = 0, TotalRemoved = 0, LastScan = "Never", LastScanClock = 0, ScanDirty = true, } --================================================== -- SINGLE INSTANCE GUARD --================================================== local ENV = (type(getgenv) == "function" and getgenv()) or _G local INSTANCE_KEY = "__RuckInspector" local function sweepOrphans() local parents = {} if type(gethui) == "function" then pcall(function() table.insert(parents, gethui()) end) end pcall(function() table.insert(parents, game:GetService("CoreGui")) end) pcall(function() local lp = game:GetService("Players").LocalPlayer local pg = lp and lp:FindFirstChild("PlayerGui") if pg then table.insert(parents, pg) end end) for _, parent in ipairs(parents) do pcall(function() while true do local found = parent:FindFirstChild(CONTAINER_NAME) if not found then break end found:Destroy() end end) end end local previous = ENV[INSTANCE_KEY] if previous and type(previous.Unload) == "function" then pcall(previous.Unload) task.wait(0.2) -- let the old window finish closing end ENV[INSTANCE_KEY] = nil sweepOrphans() --================================================== -- LOGGING --================================================== local function log(message) print(("[Ruck Inspector][%s] %s"):format( os.date("%H:%M:%S"), tostring(message) )) end local function addLog(message) table.insert(State.Logs, { Time = os.date("%H:%M:%S"), Message = tostring(message), }) while #State.Logs > CONFIG.MaxLogs do table.remove(State.Logs, 1) end log(message) end --================================================== -- NOTIFICATIONS --================================================== local function notify(title, content, duration) if not WindUI then warn("[Ruck Inspector] WindUI unavailable.") return end local ok, err = pcall(function() WindUI:Notify({ Title = title, Content = content, Duration = duration or 3, }) end) if not ok then warn("[Ruck Inspector] Notification error: " .. tostring(err)) end end local function safeNotify(title, content, duration) if CONFIG.Notifications then notify(title, content, duration) end end --================================================== -- CONNECTION MANAGEMENT --================================================== local function trackConnection(connection) table.insert(Connections, connection) return connection end local function disconnectAll() for _, connection in ipairs(Connections) do pcall(function() connection:Disconnect() end) end table.clear(Connections) end --================================================== -- WINDUI LOADER --================================================== local function loadWindUI() if type(loadstring) ~= "function" then error("Executor does not expose loadstring.") end local sourceUrl = "https://github.com/Footagesus/WindUI/releases/download/" .. WINDUI_VERSION .. "/main.lua" local response = game:HttpGet(sourceUrl) if type(response) ~= "string" or #response < 1000 then error("Invalid WindUI download response.") end local chunk, compileError = loadstring(response) if not chunk then error("WindUI compilation failed: " .. tostring(compileError)) end local ok, result = pcall(chunk) if not ok then error("WindUI initialization failed: " .. tostring(result)) end if type(result) ~= "table" or type(result.CreateWindow) ~= "function" then error("WindUI CreateWindow API unavailable.") end return result end local loadOK, loadResult = pcall(loadWindUI) if not loadOK then warn("[Ruck Inspector] INITIALIZATION FAILED") warn(tostring(loadResult)) return end WindUI = loadResult log("WindUI " .. WINDUI_VERSION .. " loaded.") --================================================== -- SERVICES --================================================== local Players = game:GetService("Players") local Workspace = game:GetService("Workspace") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local LocalPlayer = Players.LocalPlayer --================================================== -- VISUAL CONTAINER --================================================== local function createContainer() local folder = Instance.new("Folder") folder.Name = CONTAINER_NAME local parent = nil if type(gethui) == "function" then pcall(function() parent = gethui() end) end if not parent then pcall(function() parent = game:GetService("CoreGui") end) end local ok = parent ~= nil and pcall(function() folder.Parent = parent end) if not ok or not folder.Parent then folder.Parent = LocalPlayer:WaitForChild("PlayerGui") end return folder end Container = createContainer() --================================================== -- CATEGORY DEFINITIONS --================================================== local CATEGORIES = { { Key = "Mobs", Title = "Mobs", Path = { "Mobs" }, Color = Color3.fromRGB(255, 85, 85), Default = true, MaxDistance = 500, Known = { "Cow", "Goblin" }, }, { Key = "Chests", Title = "Chests", Path = { "World", "Chests" }, Color = Color3.fromRGB(255, 215, 0), Default = true, MaxDistance = 1000, Known = { "LootChestBlue", "LootChestFree", "LootChestOrange", "LootChestWhite", "StarterChest", }, }, { Key = "Shrines", Title = "Shrines", Path = { "World", "Shrines" }, Color = Color3.fromRGB(190, 120, 255), Default = true, MaxDistance = 1500, Known = { "BossShrineChief", "BossShrineChunk", "BossShrineGronk", "BossShrineGuardian", "ShrineCombat", "TotemRespawn", }, }, { Key = "Camps", Title = "Camps", Path = { "World", "Camps" }, Color = Color3.fromRGB(255, 160, 60), Default = false, MaxDistance = 1000, Known = { "Anvil", "Cart", "Cauldron", "Cave", "ChestPlayer", "ChestRock", "Fireplace", "FletchingTable", "House_Cook", "House_Fletch", "House_Miner", "House_Smith", "House_Wood", }, }, { Key = "Resources", Title = "Resources", Path = { "World", "Resources" }, Color = Color3.fromRGB(90, 200, 120), Default = false, MaxDistance = 300, Known = { "Adamantite", "AshRock", "AshRockLarge", "Barrel", "BasaltSlab", "BasaltSpire", "Birch", "Coal", "DarkOak", "Fir", "Gold", "Iron", "Log", "LogPile", "MagmaCoal", "Mihtril", "Oak", "Obamium", "ObsidianRock", "Rock", "RockPile", "Ruby", "ScorchedTree", "SulfurRock", "Tent", "Tree", }, }, { Key = "Pickups", Title = "Pickups", Path = { "World", "Pickups" }, Color = Color3.fromRGB(120, 200, 255), Default = false, MaxDistance = 300, Known = { "Apple", "CoalPickup", "Flint", "Flower", "MushroomOrange", "MushroomPink", "MushroomRed", "MushroomSus", "RockPickup", "Wheat", }, }, } -- Per-type color overrides. local TYPE_COLORS = { Goblin = Color3.fromRGB(255, 85, 85), Cow = Color3.fromRGB(235, 235, 235), Gold = Color3.fromRGB(255, 215, 0), Ruby = Color3.fromRGB(230, 40, 80), Obamium = Color3.fromRGB(255, 0, 255), Adamantite = Color3.fromRGB(80, 220, 200), Mihtril = Color3.fromRGB(120, 160, 255), Iron = Color3.fromRGB(200, 200, 210), Coal = Color3.fromRGB(150, 150, 150), } -- Extra info shown in the label (chest open costs, as observed). local TYPE_NOTES = { LootChestWhite = "25g", LootChestBlue = "80g", LootChestOrange = "200g", LootChestFree = "free?", } local CatState = {} local function toSet(list) local set = {} if type(list) == "string" then set[list] = true elseif type(list) == "table" then for key, value in pairs(list) do if type(value) == "string" then set[value] = true elseif value == true and type(key) == "string" then set[key] = true end end end return set end for _, cat in ipairs(CATEGORIES) do cat.KnownSet = toSet(cat.Known) CatState[cat.Key] = { Enabled = cat.Default, MaxDistance = cat.MaxDistance, Selected = toSet(cat.Known), } end --================================================== -- GENERAL HELPERS --================================================== local function resolvePath(path) local current = Workspace for _, name in ipairs(path) do current = current and current:FindFirstChild(name) end return current end local function typeOf(name) local base = tostring(name) base = base:gsub("%s*%(%d+%)$", "") base = base:match("^(.-)_%d+$") or base return base end local function colorFor(cat, typeName) if TYPE_COLORS[typeName] then return TYPE_COLORS[typeName] end if typeName:find("^BossShrine") then return Color3.fromRGB(255, 60, 160) end return cat.Color end local function isTypeVisible(cat, cs, typeName) if cat.KnownSet[typeName] then return cs.Selected[typeName] == true end -- Unknown / newly discovered types are always shown. return true end -- Returns only the top-most Models / BaseParts under root -- (a part inside a model is not listed separately). local function getTopLevel(root) local results = {} if not root then return results end for _, descendant in ipairs(root:GetDescendants()) do if descendant:IsA("Model") or descendant:IsA("BasePart") then local nested = false local parent = descendant.Parent while parent and parent ~= root do if parent:IsA("Model") or parent:IsA("BasePart") then nested = true break end parent = parent.Parent end if not nested then table.insert(results, descendant) end end end return results end local function getAdornPart(obj) if obj:IsA("BasePart") then return obj end if obj:IsA("Model") then if obj.PrimaryPart then return obj.PrimaryPart end for _, descendant in ipairs(obj:GetDescendants()) do if descendant:IsA("BasePart") then return descendant end end end return nil end local function getPosition(obj) local ok, pos = pcall(function() return obj:GetPivot().Position end) if ok then return pos end return nil end local function getOrigin() local character = LocalPlayer and LocalPlayer.Character local root = character and character:FindFirstChild("HumanoidRootPart") if root then return root.Position end local camera = Workspace.CurrentCamera if camera then return camera.CFrame.Position end return Vector3.new(0, 0, 0) end local function countParts(obj) local count = 0 for _, descendant in ipairs(obj:GetDescendants()) do if descendant:IsA("BasePart") then count += 1 end end return count end --================================================== -- ESP ENTRIES --================================================== local function removeHighlight(entry) if entry.Highlight then pcall(function() entry.Highlight:Destroy() end) entry.Highlight = nil end end local function ensureHighlight(entry) if entry.Highlight and entry.Highlight.Parent then return end local highlight = Instance.new("Highlight") highlight.Name = "RuckESPHighlight" highlight.Adornee = entry.Obj highlight.FillColor = entry.Color highlight.OutlineColor = Color3.fromRGB(255, 255, 255) highlight.FillTransparency = 0.7 highlight.OutlineTransparency = 0 highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop highlight.Parent = Container entry.Highlight = highlight end local function removeEntry(obj) local entry = Entries[obj] if not entry then return end removeHighlight(entry) if entry.Gui then pcall(function() entry.Gui:Destroy() end) end Entries[obj] = nil State.TotalRemoved += 1 end local function clearAllEntries() for obj in pairs(Entries) do removeEntry(obj) end table.clear(Entries) end local function removeCategoryEntries(cat) for obj, entry in pairs(Entries) do if entry.Cat == cat then removeEntry(obj) end end end local function createEntry(cat, obj, typeName) local part = getAdornPart(obj) if not part then return end local height = 3 pcall(function() if obj:IsA("Model") then height = obj:GetExtentsSize().Y / 2 else height = obj.Size.Y / 2 end end) height = math.clamp(height + 1.5, 2, 30) local color = colorFor(cat, typeName) local gui = Instance.new("BillboardGui") gui.Name = "RuckESPLabel" gui.Adornee = part gui.Size = UDim2.fromOffset(220, 20) gui.StudsOffset = Vector3.new(0, height, 0) gui.AlwaysOnTop = true gui.LightInfluence = 0 gui.Parent = Container local label = Instance.new("TextLabel") label.Size = UDim2.fromScale(1, 1) label.BackgroundTransparency = 1 label.Text = typeName label.TextColor3 = color label.TextStrokeTransparency = 0.3 label.TextSize = 14 label.Font = Enum.Font.GothamBold label.Parent = gui local humanoid = nil if obj:IsA("Model") then humanoid = obj:FindFirstChildOfClass("Humanoid") end Entries[obj] = { Obj = obj, Cat = cat, Type = typeName, Part = part, Gui = gui, Label = label, Color = color, Humanoid = humanoid, Dist = 0, Text = "", } State.TotalCreated += 1 end local function buildText(entry) local text = entry.Type local note = TYPE_NOTES[entry.Type] if note then text = text .. " (" .. note .. ")" end if Settings.ShowDistance then text = text .. " [" .. math.floor(entry.Dist) .. "m]" end if Settings.ShowHealth then local health, maxHealth if entry.Humanoid and entry.Humanoid.Parent then health = entry.Humanoid.Health maxHealth = entry.Humanoid.MaxHealth else local attrHealth = entry.Obj:GetAttribute("Health") local attrMax = entry.Obj:GetAttribute("MaxHealth") if type(attrHealth) == "number" then health = attrHealth maxHealth = type(attrMax) == "number" and attrMax or nil end end if health then if maxHealth then text = text .. " " .. math.floor(health) .. "/" .. math.floor(maxHealth) else text = text .. " " .. math.floor(health) .. "hp" end end end return text end --================================================== -- SCANNING --================================================== local function requestScan() State.ScanDirty = true end local missingWarned = {} local function scanAll() local origin = getOrigin() for _, cat in ipairs(CATEGORIES) do local cs = CatState[cat.Key] if not cs.Enabled then removeCategoryEntries(cat) else local root = resolvePath(cat.Path) if not root then removeCategoryEntries(cat) if not missingWarned[cat.Key] then missingWarned[cat.Key] = true addLog(cat.Title .. " folder not found: Workspace." .. table.concat(cat.Path, ".")) end else missingWarned[cat.Key] = nil local seen = {} for _, obj in ipairs(getTopLevel(root)) do local typeName = typeOf(obj.Name) if isTypeVisible(cat, cs, typeName) then local pos = getPosition(obj) if pos and (pos - origin).Magnitude <= cs.MaxDistance then seen[obj] = true if not Entries[obj] then createEntry(cat, obj, typeName) end end end end for obj, entry in pairs(Entries) do if entry.Cat == cat and not seen[obj] then removeEntry(obj) end end end end end State.LastScan = os.date("%H:%M:%S") end local function updateEntries() local origin = getOrigin() local list = {} for obj, entry in pairs(Entries) do local cs = CatState[entry.Cat.Key] if not cs.Enabled or not obj:IsDescendantOf(Workspace) then removeEntry(obj) else if not entry.Part or not entry.Part:IsDescendantOf(Workspace) then entry.Part = getAdornPart(obj) if entry.Part then entry.Gui.Adornee = entry.Part end end local pos = getPosition(obj) if not entry.Part or not pos then removeEntry(obj) else entry.Dist = (pos - origin).Magnitude local text = buildText(entry) if text ~= entry.Text then entry.Text = text entry.Label.Text = text end table.insert(list, entry) end end end if Settings.Highlights then table.sort(list, function(a, b) return a.Dist < b.Dist end) for index, entry in ipairs(list) do if index <= Settings.MaxHighlights then ensureHighlight(entry) else removeHighlight(entry) end end else for _, entry in ipairs(list) do removeHighlight(entry) end end end --================================================== -- INSPECTION TOOLS --================================================== local function inspectPath(path) local label = "Workspace." .. table.concat(path, ".") local folder = resolvePath(path) print("\n========== " .. label .. " ==========") if not folder then print("Not found.") addLog(label .. " not found.") return end local models, parts, folders = 0, 0, 0 local descendants = folder:GetDescendants() for _, object in ipairs(descendants) do if object:IsA("Model") then models += 1 elseif object:IsA("BasePart") then parts += 1 elseif object:IsA("Folder") then folders += 1 end end print("Direct children:", #folder:GetChildren()) print("Total descendants:", #descendants) print("Models:", models, "BaseParts:", parts, "Folders:", folders) print("\nDirect children:") for _, child in ipairs(folder:GetChildren()) do print(child.Name, "[" .. child.ClassName .. "]", "Children:", #child:GetChildren()) end print("==========================================\n") addLog(label .. " inspection completed.") end local function inspectWorkspaceOverview() print("\n========== WORKSPACE OVERVIEW ==========") for _, child in ipairs(Workspace:GetChildren()) do print(child.Name, "[" .. child.ClassName .. "]", "Children:", #child:GetChildren()) end print("========================================\n") addLog("Workspace overview printed.") end local function inspectObject(obj) if not obj then return end print("\n========== OBJECT STRUCTURE ==========") print("Name:", obj.Name) print("Class:", obj.ClassName) print("FullName:", obj:GetFullName()) local pos = getPosition(obj) print("Position:", pos and tostring(pos) or "Unknown") if obj:IsA("Model") then print("PrimaryPart:", obj.PrimaryPart and obj.PrimaryPart.Name or "None") print("Direct children:", #obj:GetChildren()) print("Total descendants:", #obj:GetDescendants()) print("BaseParts:", countParts(obj)) local humanoid = obj:FindFirstChildOfClass("Humanoid") if humanoid then print("Humanoid:", humanoid.Health .. "/" .. humanoid.MaxHealth) else print("Humanoid: None") end end local attributes = {} pcall(function() attributes = obj:GetAttributes() end) print("\nAttributes:") local hasAttributes = false for key, value in pairs(attributes) do hasAttributes = true print(" " .. tostring(key) .. " =", value) end if not hasAttributes then print(" (none)") end local function printHierarchy(parent, depth) if depth > 8 then print(string.rep(" ", depth) .. "... depth limit") return end for _, child in ipairs(parent:GetChildren()) do print(string.rep(" ", depth) .. child.Name, "[" .. child.ClassName .. "]") printHierarchy(child, depth + 1) end end print("\nHierarchy:") printHierarchy(obj, 0) print("======================================\n") end local function inspectNearest() local origin = getOrigin() local nearest, nearestDist, nearestCat = nil, math.huge, nil for _, cat in ipairs(CATEGORIES) do local root = resolvePath(cat.Path) for _, obj in ipairs(getTopLevel(root)) do local pos = getPosition(obj) if pos then local dist = (pos - origin).Magnitude if dist < nearestDist then nearest, nearestDist, nearestCat = obj, dist, cat end end end end if not nearest then addLog("No nearby objects found.") return end print(("Nearest object: %s (%s) at %d studs"):format( nearest.Name, nearestCat.Title, math.floor(nearestDist) )) inspectObject(nearest) addLog("Inspected nearest object: " .. nearest.Name) end local function typeCensus() print("\n========== TYPE CENSUS ==========") for _, cat in ipairs(CATEGORIES) do local root = resolvePath(cat.Path) print("\n[" .. cat.Title .. "] Workspace." .. table.concat(cat.Path, ".")) if not root then print(" Folder not found.") else local counts = {} local total = 0 for _, obj in ipairs(getTopLevel(root)) do local typeName = typeOf(obj.Name) counts[typeName] = (counts[typeName] or 0) + 1 total += 1 end local names = {} for name in pairs(counts) do table.insert(names, name) end table.sort(names) print(" Total objects:", total) for _, name in ipairs(names) do print( " " .. name, counts[name], cat.KnownSet[name] and "" or "<-- NEW (not in filter list)" ) end end end print("\n=================================\n") addLog("Type census completed.") end local function printLogs() print("\n========== RUCK INSPECTOR LOGS ==========") if #State.Logs == 0 then print("No events recorded.") end for _, entry in ipairs(State.Logs) do print("[" .. entry.Time .. "] " .. entry.Message) end print("=========================================\n") end local function printReport() local counts = {} local total = 0 for _, entry in pairs(Entries) do counts[entry.Cat.Key] = (counts[entry.Cat.Key] or 0) + 1 total += 1 end print("\n========== INSPECTOR REPORT ==========") print("Version:", VERSION) print("WindUI:", WINDUI_VERSION) print("Player:", LocalPlayer and LocalPlayer.Name or "Unavailable") print("PlaceId:", game.PlaceId) print("GameId:", game.GameId) print("Active ESP objects:", total) for _, cat in ipairs(CATEGORIES) do local cs = CatState[cat.Key] print( " " .. cat.Title .. ":", counts[cat.Key] or 0, cs.Enabled and "(ON, " .. cs.MaxDistance .. "m)" or "(off)" ) end print("Total created:", State.TotalCreated) print("Total removed:", State.TotalRemoved) print("Last scan:", State.LastScan) print("======================================\n") end --================================================== -- WINDOW --================================================== Window = WindUI:CreateWindow({ Title = "RUCK | Inspector AIO", Author = "Author: asuralangley - AIO v" .. VERSION, Icon = "swords", Theme = "Dark", Size = UDim2.fromOffset(680, 500), MinSize = Vector2.new(560, 400), Resizable = true, HideSearchBar = false, Folder = "RuckInspector", }) --================================================== -- CUSTOM TOGGLE KEYBIND -- (WindUI's built-in ToggleKey is intentionally not used, -- so only one handler ever toggles the window.) --================================================== local TOGGLE_KEYS = { [Enum.KeyCode.RightShift] = true, [Enum.KeyCode.RightControl] = true, } local windowOpen = true local lastToggle = 0 local function toggleWindow() if os.clock() - lastToggle < 0.15 then return end lastToggle = os.clock() local ok = pcall(function() Window:Toggle() end) if not ok then if windowOpen then ok = pcall(function() Window:Close() end) else ok = pcall(function() Window:Open() end) end end if ok then windowOpen = not windowOpen log("Window toggled.") else warn("[Ruck Inspector] Could not toggle window (no Toggle/Open/Close method).") end end trackConnection(UserInputService.InputBegan:Connect(function(input) if input.UserInputType ~= Enum.UserInputType.Keyboard then return end if not TOGGLE_KEYS[input.KeyCode] then return end if UserInputService:GetFocusedTextBox() then return end toggleWindow() end)) pcall(function() Window:Tag({ Title = "v" .. VERSION, Color = "Success", }) end) local Dashboard = Window:Tab({ Title = "Dashboard", Icon = "layout-dashboard", }) local MobsTab = Window:Tab({ Title = "Mobs", Icon = "skull", }) local WorldTab = Window:Tab({ Title = "World", Icon = "globe", }) local DiagnosticsTab = Window:Tab({ Title = "Diagnostics", Icon = "scan-search", }) local SettingsTab = Window:Tab({ Title = "Settings", Icon = "settings", }) --================================================== -- UI HELPERS --================================================== local function addSection(tab, title) local ok = pcall(function() tab:Section({ Title = title }) end) if not ok then pcall(function() tab:Paragraph({ Title = title, Desc = "" }) end) end end local function tryElement(description, fn) local ok, err = pcall(fn) if not ok then addLog("UI element failed (" .. description .. "): " .. tostring(err)) end end local function copyList(list) local copy = {} for _, value in ipairs(list) do table.insert(copy, value) end return copy end local function buildCategoryUI(tab, cat) local cs = CatState[cat.Key] addSection(tab, cat.Title) tryElement(cat.Title .. " toggle", function() tab:Toggle({ Title = "Show " .. cat.Title .. " ESP", Value = cs.Enabled, Callback = function(value) cs.Enabled = value requestScan() addLog(cat.Title .. " ESP: " .. tostring(value)) end, }) end) tryElement(cat.Title .. " distance", function() tab:Slider({ Title = cat.Title .. " Max Distance", Step = 10, Value = { Min = 50, Max = 3000, Default = cs.MaxDistance, }, Callback = function(value) local number = tonumber(value) if number then cs.MaxDistance = number requestScan() end end, }) end) tryElement(cat.Title .. " types", function() tab:Dropdown({ Title = cat.Title .. " Types", Values = copyList(cat.Known), Value = copyList(cat.Known), Multi = true, AllowNone = true, Callback = function(selection) cs.Selected = toSet(selection) requestScan() end, }) end) end --================================================== -- DASHBOARD --================================================== Dashboard:Paragraph({ Title = "RUCK Inspector AIO", Desc = "Version " .. VERSION .. " | WindUI " .. WINDUI_VERSION, }) Dashboard:Paragraph({ Title = "Quick Start", Desc = "Mobs, Chests and Shrines ESP are on by default. Enable Camps, Resources and Pickups in the World tab. Run Type Census in Diagnostics to find new mob species or items.", }) Dashboard:Button({ Title = "Rescan Now", Icon = "refresh-cw", Callback = function() requestScan() safeNotify("Scan", "Rescan requested.") end, }) Dashboard:Button({ Title = "Print Full Report", Icon = "file-text", Callback = function() printReport() safeNotify("Report", "Report printed to console.") end, }) Dashboard:Button({ Title = "Show Event Logs", Icon = "scroll-text", Callback = printLogs, }) --================================================== -- MOBS TAB --================================================== buildCategoryUI(MobsTab, CATEGORIES[1]) MobsTab:Button({ Title = "Print Mob Species Census", Icon = "bar-chart", Callback = typeCensus, }) --================================================== -- WORLD TAB --================================================== for index = 2, #CATEGORIES do buildCategoryUI(WorldTab, CATEGORIES[index]) end --================================================== -- DIAGNOSTICS --================================================== DiagnosticsTab:Paragraph({ Title = "Runtime Diagnostics", Desc = "Everything prints to the executor console (F9).", }) DiagnosticsTab:Button({ Title = "Workspace Overview", Icon = "layers", Callback = inspectWorkspaceOverview, }) DiagnosticsTab:Button({ Title = "Type Census (All Categories)", Icon = "bar-chart", Callback = typeCensus, }) DiagnosticsTab:Button({ Title = "Inspect Nearest Object", Icon = "crosshair", Callback = inspectNearest, }) DiagnosticsTab:Button({ Title = "Inspect Mobs Folder", Icon = "skull", Callback = function() inspectPath({ "Mobs" }) end, }) DiagnosticsTab:Button({ Title = "Inspect MobVisuals Folder", Icon = "eye", Callback = function() inspectPath({ "MobVisuals" }) end, }) DiagnosticsTab:Button({ Title = "Inspect World Folder", Icon = "globe", Callback = function() inspectPath({ "World" }) end, }) DiagnosticsTab:Button({ Title = "Run Environment Diagnostics", Icon = "scan", Callback = function() print("\n========== ENVIRONMENT DIAGNOSTICS ==========") print("WindUI loaded:", WindUI ~= nil and "PASS" or "FAIL") print("LocalPlayer available:", LocalPlayer ~= nil and "PASS" or "FAIL") print("Visual container:", Container and Container.Parent and "PASS" or "FAIL") print("MobVisuals folder:", Workspace:FindFirstChild("MobVisuals") and "PASS" or "FAIL") for _, cat in ipairs(CATEGORIES) do print( cat.Title .. " folder:", resolvePath(cat.Path) and "PASS" or "FAIL" ) end print("PlaceId:", game.PlaceId) print("GameId:", game.GameId) print("RunService:", RunService ~= nil and "PASS" or "FAIL") print("==============================================\n") addLog("Environment diagnostics completed.") safeNotify("Diagnostics", "Diagnostics printed to console.") end, }) DiagnosticsTab:Button({ Title = "Show Event Logs", Icon = "scroll-text", Callback = printLogs, }) --================================================== -- SETTINGS --================================================== SettingsTab:Paragraph({ Title = "General Settings", Desc = "Configure ESP display and interface behavior.", }) SettingsTab:Toggle({ Title = "Show Distance", Value = Settings.ShowDistance, Callback = function(value) Settings.ShowDistance = value end, }) SettingsTab:Toggle({ Title = "Show Health (when available)", Value = Settings.ShowHealth, Callback = function(value) Settings.ShowHealth = value end, }) SettingsTab:Toggle({ Title = "Highlights (nearest 30)", Value = Settings.Highlights, Callback = function(value) Settings.Highlights = value addLog("Highlights: " .. tostring(value)) end, }) tryElement("scan interval", function() SettingsTab:Slider({ Title = "Scan Interval (seconds)", Step = 0.5, Value = { Min = 0.5, Max = 5, Default = Settings.ScanInterval, }, Callback = function(value) local number = tonumber(value) if number then Settings.ScanInterval = number end end, }) end) SettingsTab:Toggle({ Title = "Notifications", Value = CONFIG.Notifications, Callback = function(value) CONFIG.Notifications = value addLog("Notifications: " .. tostring(value)) if value then notify("Settings", "Notifications enabled.") end end, }) SettingsTab:Button({ Title = "Disable All ESP", Icon = "eye-off", Callback = function() for _, cat in ipairs(CATEGORIES) do CatState[cat.Key].Enabled = false end clearAllEntries() addLog("All ESP disabled (toggle categories back on to re-enable).") safeNotify("ESP", "All ESP cleared.") end, }) SettingsTab:Button({ Title = "Clear Event Logs", Icon = "trash-2", Callback = function() table.clear(State.Logs) log("Event logs cleared.") safeNotify("Logs", "Event logs cleared.") end, }) SettingsTab:Button({ Title = "Print Configuration", Icon = "settings-2", Callback = function() print("\n========== CONFIGURATION ==========") for key, value in pairs(CONFIG) do print(key, value) end for key, value in pairs(Settings) do print("Settings." .. key, value) end for _, cat in ipairs(CATEGORIES) do local cs = CatState[cat.Key] print(cat.Key, "Enabled:", cs.Enabled, "MaxDistance:", cs.MaxDistance) end print("===================================\n") end, }) --================================================== -- BACKGROUND LOOPS --================================================== -- Scan loop: finds new objects, removes ones that left range or filter. task.spawn(function() while State.Running do if State.ScanDirty or os.clock() - State.LastScanClock >= Settings.ScanInterval then State.ScanDirty = false State.LastScanClock = os.clock() local ok, err = pcall(scanAll) if not ok then addLog("Scan error: " .. tostring(err)) end end task.wait(0.25) end end) -- Update loop: distances, health text, highlight ranking. task.spawn(function() while State.Running do local ok, err = pcall(updateEntries) if not ok then addLog("Update error: " .. tostring(err)) end task.wait(0.25) end end) --================================================== -- CLEANUP / UNLOAD --================================================== local function unload() if not State.Running then return end State.Running = false if ENV[INSTANCE_KEY] and ENV[INSTANCE_KEY].Unload == unload then ENV[INSTANCE_KEY] = nil end clearAllEntries() disconnectAll() if Container then pcall(function() Container:Destroy() end) end addLog("Inspector unloading.") local destroyed = false for _, methodName in ipairs({ "Destroy", "Close" }) do local method = Window and Window[methodName] if type(method) == "function" then local ok = pcall(function() method(Window) end) if ok then destroyed = true break end end end if not destroyed then warn("[Ruck Inspector] Window cleanup method unavailable.") end print("[Ruck Inspector] Unload completed.") end -- Register this instance so the next execution can replace it. ENV[INSTANCE_KEY] = { Unload = unload } SettingsTab:Button({ Title = "Unload UI", Icon = "power", Callback = unload, }) --================================================== -- READY --================================================== addLog("Ruck Inspector AIO v" .. VERSION .. " initialized.") safeNotify( "Ruck Inspector", "AIO v" .. VERSION .. " loaded successfully.", 5 ) print("[Ruck Inspector] AIO v" .. VERSION .. " loaded.") print("[Ruck Inspector] Run 'Type Census' in Diagnostics to discover all species and items.")