Roblox Asset Loading Tracker
Key RequiredUniversal

Roblox Asset Loading Tracker

Universal ScriptGBernGBern 1.8K views 20 executesUpdated Apr 12, 2025
5.0/ 5(5 votes)
50100% Positive
Lua Script•1200 lines (38381 chars)
local ContentProvider = game:GetService("ContentProvider")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local Lighting = game:GetService("Lighting")
local MaterialService = game:GetService("MaterialService")
local SoundService = game:GetService("SoundService")
local StarterPack = game:GetService("StarterPack")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Stats = game:GetService("Stats")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")

local LocalPlayer = Players.LocalPlayer or Players:WaitForChild("LocalPlayer")

if not _G.TrackerLoadedAssetIds then
    _G.TrackerLoadedAssetIds = {}
end

local CONFIG = {
    BatchSize = 25,
    SearchDebounce = 0.15,
    AnimSpeed = 0.18,
    MinWidth = 380,
    MinHeight = 190,
    MaxWidth = 880,
    MaxHeight = 650,
}

local THEME = {
    BgMain      = Color3.fromRGB(15, 17, 21),
    BgSecondary = Color3.fromRGB(22, 25, 31),
    BgCard      = Color3.fromRGB(28, 31, 39),
    Border      = Color3.fromRGB(40, 44, 54),
    TextPrimary = Color3.fromRGB(241, 245, 249),
    TextMuted   = Color3.fromRGB(148, 163, 184),
    TextDim     = Color3.fromRGB(90, 98, 115),
    Accent      = Color3.fromRGB(56, 189, 248),
    Success     = Color3.fromRGB(52, 211, 153),
    SuccessBg   = Color3.fromRGB(20, 38, 28),
    Danger      = Color3.fromRGB(248, 113, 113),
}

local function create(className: string, props: {[string]: any}?): any
    local inst = Instance.new(className)
    if props then
        local parent = props.Parent
        for k, v in pairs(props) do
            if k ~= "Parent" then
                (inst :: any)[k] = v
            end
        end
        if parent then
            inst.Parent = parent
        end
    end
    return inst
end

local function corner(parent: Instance, radius: number): UICorner
    local c = Instance.new("UICorner")
    c.CornerRadius = UDim.new(0, radius)
    c.Parent = parent
    return c
end

local function stroke(parent: Instance, color: Color3, thickness: number?): UIStroke
    local s = Instance.new("UIStroke")
    s.Color = color
    s.Thickness = thickness or 1
    s.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
    s.Parent = parent
    return s
end

local function getGuiRoot(): Instance
    local ok, target = pcall(function()
        return (typeof(gethui) == "function" and gethui()) or game:GetService("CoreGui")
    end)
    if ok and target then
        local canParent = pcall(function()
            local t = Instance.new("Folder")
            t.Parent = target
            t:Destroy()
        end)
        if canParent then return target end
    end
    return LocalPlayer:WaitForChild("PlayerGui")
end

type FailedRecord = {
    id: string,
    name: string,
    fullName: string,
    assetType: string,
    contentId: string,
    targetInstance: Instance?,
    reason: string,
    retries: number,
}

local ASSET_CLASSES: {[string]: string} = {
    MeshPart = "Mesh", SpecialMesh = "Mesh", Decal = "Decal", Texture = "Texture",
    SurfaceAppearance = "PBR Material", Sound = "Audio", Animation = "Animation",
    ImageLabel = "UI Image", ImageButton = "UI Image", ParticleEmitter = "VFX Particle",
    Beam = "VFX Beam", Trail = "VFX Trail", Sky = "Skybox", Shirt = "Clothing",
    Pants = "Clothing", ShirtGraphic = "Graphic",
}

local state = {
    totalInstances = 0,
    processedInstances = 0,
    totalFiles = 0,
    recoveredCount = 0,
    failed = {} :: {FailedRecord},
    failedSeen = {} :: {[string]: boolean},
    isComplete = false,
    startTime = 0,
    elapsedTime = 0,
    isRunning = false,
    speed = 0,
    isMinimized = false,
    activeTab = "monitor",
    savedSize = UDim2.new(0, 440, 0, 210),
}

local function isTrackable(inst: Instance): boolean
    return ASSET_CLASSES[inst.ClassName] ~= nil
end

local function getAssetType(inst: Instance): string
    return ASSET_CLASSES[inst.ClassName] or inst.ClassName
end

local function formatPath(inst: Instance): string
    local full = inst:GetFullName()
    return (#full > 48) and ("..." .. string.sub(full, -45)) or full
end

local function formatClock(sec: number): string
    return string.format("%02d:%02d", math.floor(sec / 60), math.floor(sec % 60))
end

local ScreenGui = create("ScreenGui", {
    Name = "DevAssetProfiler",
    ResetOnSpawn = false,
    DisplayOrder = 99999,
    Parent = getGuiRoot(),
})

local RootFrame = create("Frame", {
    Name = "Root",
    Size = state.savedSize,
    Position = UDim2.new(0.5, -220, 0.5, -105),
    BackgroundColor3 = THEME.BgMain,
    BorderSizePixel = 0,
    ClipsDescendants = true,
    Parent = ScreenGui,
})
corner(RootFrame, 8)
stroke(RootFrame, THEME.Border)

local Header = create("Frame", {
    Name = "Header",
    Size = UDim2.new(1, 0, 0, 36),
    BackgroundColor3 = THEME.BgSecondary,
    BorderSizePixel = 0,
    Parent = RootFrame,
})
corner(Header, 8)

create("Frame", {
    Size = UDim2.new(1, 0, 0, 1),
    Position = UDim2.new(0, 0, 1, -1),
    BackgroundColor3 = THEME.Border,
    BorderSizePixel = 0,
    Parent = Header,
})

local StatusDot = create("Frame", {
    Size = UDim2.new(0, 7, 0, 7),
    Position = UDim2.new(0, 14, 0.5, -3),
    BackgroundColor3 = THEME.Accent,
    BorderSizePixel = 0,
    Parent = Header,
})
corner(StatusDot, 10)

local TitleLabel = create("TextLabel", {
    Size = UDim2.new(0, 100, 1, 0),
    Position = UDim2.new(0, 28, 0, 0),
    BackgroundTransparency = 1,
    TextColor3 = THEME.TextPrimary,
    Font = Enum.Font.RobotoMono,
    TextSize = 12,
    Text = "asset.loader",
    TextXAlignment = Enum.TextXAlignment.Left,
    Parent = Header,
})

local TabNav = create("Frame", {
    Size = UDim2.new(0, 160, 0, 22),
    Position = UDim2.new(0, 126, 0.5, -11),
    BackgroundColor3 = THEME.BgMain,
    BorderSizePixel = 0,
    Parent = Header,
})
corner(TabNav, 5)
stroke(TabNav, THEME.Border)

local TabMonitorBtn = create("TextButton", {
    Size = UDim2.new(0.5, 0, 1, 0),
    BackgroundColor3 = THEME.BgCard,
    TextColor3 = THEME.TextPrimary,
    Font = Enum.Font.GothamMedium,
    TextSize = 10,
    Text = "Monitor",
    BorderSizePixel = 0,
    Parent = TabNav,
})
corner(TabMonitorBtn, 5)

local TabErrorsBtn = create("TextButton", {
    Size = UDim2.new(0.5, 0, 1, 0),
    Position = UDim2.new(0.5, 0, 0, 0),
    BackgroundTransparency = 1,
    TextColor3 = THEME.TextMuted,
    Font = Enum.Font.GothamMedium,
    TextSize = 10,
    Text = "Errors (0)",
    BorderSizePixel = 0,
    Parent = TabNav,
})
corner(TabErrorsBtn, 5)

local MinBtn = create("TextButton", {
    Size = UDim2.new(0, 24, 0, 22),
    Position = UDim2.new(1, -32, 0.5, -11),
    BackgroundColor3 = THEME.BgMain,
    BorderSizePixel = 0,
    TextColor3 = THEME.TextMuted,
    Font = Enum.Font.GothamBold,
    TextSize = 11,
    Text = "-",
    Parent = Header,
})
corner(MinBtn, 5)
stroke(MinBtn, THEME.Border)

local MonitorPage = create("Frame", {
    Name = "MonitorPage",
    Size = UDim2.new(1, -24, 1, -48),
    Position = UDim2.new(0, 12, 0, 44),
    BackgroundTransparency = 1,
    Parent = RootFrame,
})

local ProgressRow = create("Frame", {
    Size = UDim2.new(1, 0, 0, 22),
    BackgroundTransparency = 1,
    Parent = MonitorPage,
})

local PercentText = create("TextLabel", {
    Size = UDim2.new(0.35, 0, 1, 0),
    BackgroundTransparency = 1,
    Font = Enum.Font.GothamBold,
    TextSize = 18,
    TextColor3 = THEME.TextPrimary,
    Text = "0%",
    TextXAlignment = Enum.TextXAlignment.Left,
    Parent = ProgressRow,
})

local CountText = create("TextLabel", {
    Size = UDim2.new(0.65, 0, 1, 0),
    Position = UDim2.new(0.35, 0, 0, 0),
    BackgroundTransparency = 1,
    Font = Enum.Font.RobotoMono,
    TextSize = 11,
    TextColor3 = THEME.TextMuted,
    Text = "0 / 0 assets",
    TextXAlignment = Enum.TextXAlignment.Right,
    Parent = ProgressRow,
})

local ProgressTrack = create("Frame", {
    Size = UDim2.new(1, 0, 0, 4),
    Position = UDim2.new(0, 0, 0, 28),
    BackgroundColor3 = THEME.BgCard,
    BorderSizePixel = 0,
    Parent = MonitorPage,
})
corner(ProgressTrack, 2)

local ProgressBar = create("Frame", {
    Size = UDim2.new(0, 0, 1, 0),
    BackgroundColor3 = THEME.Accent,
    BorderSizePixel = 0,
    Parent = ProgressTrack,
})
corner(ProgressBar, 2)

local TargetCard = create("Frame", {
    Size = UDim2.new(1, 0, 0, 48),
    Position = UDim2.new(0, 0, 0, 40),
    BackgroundColor3 = THEME.BgSecondary,
    BorderSizePixel = 0,
    Parent = MonitorPage,
})
corner(TargetCard, 6)
stroke(TargetCard, THEME.Border)

local CurrentPath = create("TextLabel", {
    Size = UDim2.new(1, -16, 0, 18),
    Position = UDim2.new(0, 10, 0, 6),
    BackgroundTransparency = 1,
    Font = Enum.Font.RobotoMono,
    TextSize = 10,
    TextColor3 = THEME.TextPrimary,
    Text = "STANDBY",
    TextTruncate = Enum.TextTruncate.AtEnd,
    TextXAlignment = Enum.TextXAlignment.Left,
    Parent = TargetCard,
})

local CurrentMeta = create("TextLabel", {
    Size = UDim2.new(1, -16, 0, 16),
    Position = UDim2.new(0, 10, 0, 24),
    BackgroundTransparency = 1,
    Font = Enum.Font.Gotham,
    TextSize = 10,
    TextColor3 = THEME.TextDim,
    Text = "Queue pending...",
    TextXAlignment = Enum.TextXAlignment.Left,
    Parent = TargetCard,
})

local TelemetryRow = create("Frame", {
    Size = UDim2.new(1, 0, 0, 22),
    Position = UDim2.new(0, 0, 1, -22),
    BackgroundTransparency = 1,
    Parent = MonitorPage,
})

create("UIListLayout", {
    FillDirection = Enum.FillDirection.Horizontal,
    VerticalAlignment = Enum.VerticalAlignment.Center,
    Padding = UDim.new(0, 12),
    Parent = TelemetryRow,
})

local function createChip(defaultText: string): TextLabel
    return create("TextLabel", {
        AutomaticSize = Enum.AutomaticSize.X,
        Size = UDim2.new(0, 0, 1, 0),
        BackgroundTransparency = 1,
        Font = Enum.Font.RobotoMono,
        TextSize = 10,
        TextColor3 = THEME.TextDim,
        Text = defaultText,
        Parent = TelemetryRow,
    })
end

local ChipFps   = createChip("FPS --")
local ChipPing  = createChip("0ms")
local ChipSpeed = createChip("0 obj/s")
local ChipEta   = createChip("ETA --")
local ChipTime  = createChip("00:00")

local ErrorsPage = create("Frame", {
    Name = "ErrorsPage",
    Size = UDim2.new(1, -24, 1, -48),
    Position = UDim2.new(0, 12, 0, 44),
    BackgroundTransparency = 1,
    Visible = false,
    Parent = RootFrame,
})

local SearchInput = create("TextBox", {
    Size = UDim2.new(1, -90, 0, 24),
    BackgroundColor3 = THEME.BgSecondary,
    BorderSizePixel = 0,
    PlaceholderText = "Filter failed assets...",
    PlaceholderColor3 = THEME.TextDim,
    TextColor3 = THEME.TextPrimary,
    Font = Enum.Font.RobotoMono,
    TextSize = 10,
    Text = "",
    ClearTextOnFocus = false,
    Parent = ErrorsPage,
})
corner(SearchInput, 5)
stroke(SearchInput, THEME.Border)
create("UIPadding", { PaddingLeft = UDim.new(0, 8), Parent = SearchInput })

local RetryAllBtn = create("TextButton", {
    Size = UDim2.new(0, 82, 0, 24),
    Position = UDim2.new(1, -82, 0, 0),
    BackgroundColor3 = THEME.BgCard,
    BorderSizePixel = 0,
    TextColor3 = THEME.Accent,
    Font = Enum.Font.GothamMedium,
    TextSize = 10,
    Text = "Retry All",
    Parent = ErrorsPage,
})
corner(RetryAllBtn, 5)
stroke(RetryAllBtn, THEME.Border)

local ErrorScroll = create("ScrollingFrame", {
    Size = UDim2.new(1, 0, 1, -32),
    Position = UDim2.new(0, 0, 0, 32),
    BackgroundTransparency = 1,
    BorderSizePixel = 0,
    ScrollBarThickness = 4,
    ScrollBarImageColor3 = THEME.Border,
    AutomaticCanvasSize = Enum.AutomaticSize.Y,
    CanvasSize = UDim2.new(0, 0, 0, 0),
    Parent = ErrorsPage,
})
create("UIPadding", { PaddingRight = UDim.new(0, 6), Parent = ErrorScroll })

local _ErrorLayout = create("UIListLayout", {
    Padding = UDim.new(0, 5),
    SortOrder = Enum.SortOrder.LayoutOrder,
    Parent = ErrorScroll,
})

local InfoPage = create("Frame", {
    Name = "InfoPage",
    Size = UDim2.new(1, -24, 1, -48),
    Position = UDim2.new(0, 12, 0, 44),
    BackgroundTransparency = 1,
    Visible = false,
    Parent = RootFrame,
})

local InfoHeader = create("Frame", {
    Size = UDim2.new(1, 0, 0, 24),
    BackgroundTransparency = 1,
    Parent = InfoPage,
})

local InfoBackBtn = create("TextButton", {
    Size = UDim2.new(0, 54, 1, 0),
    BackgroundColor3 = THEME.BgSecondary,
    BorderSizePixel = 0,
    TextColor3 = THEME.TextMuted,
    Font = Enum.Font.GothamMedium,
    TextSize = 10,
    Text = "Back",
    Parent = InfoHeader,
})
corner(InfoBackBtn, 4)
stroke(InfoBackBtn, THEME.Border)

create("TextLabel", {
    Size = UDim2.new(1, -64, 1, 0),
    Position = UDim2.new(0, 64, 0, 0),
    BackgroundTransparency = 1,
    Font = Enum.Font.RobotoMono,
    TextSize = 11,
    TextColor3 = THEME.TextPrimary,
    Text = "Asset Diagnostics",
    TextXAlignment = Enum.TextXAlignment.Left,
    Parent = InfoHeader,
})

local InfoScroll = create("ScrollingFrame", {
    Size = UDim2.new(1, 0, 1, -58),
    Position = UDim2.new(0, 0, 0, 28),
    BackgroundColor3 = THEME.BgSecondary,
    BorderSizePixel = 0,
    ScrollBarThickness = 4,
    ScrollBarImageColor3 = THEME.Border,
    AutomaticCanvasSize = Enum.AutomaticSize.Y,
    CanvasSize = UDim2.new(0, 0, 0, 0),
    Parent = InfoPage,
})
corner(InfoScroll, 6)
stroke(InfoScroll, THEME.Border)
create("UIPadding", {
    PaddingTop = UDim.new(0, 8), PaddingBottom = UDim.new(0, 8),
    PaddingLeft = UDim.new(0, 10), PaddingRight = UDim.new(0, 10),
    Parent = InfoScroll,
})
create("UIListLayout", { Padding = UDim.new(0, 6), SortOrder = Enum.SortOrder.LayoutOrder, Parent = InfoScroll })

local function createDiagRow(label: string): TextLabel
    local box = create("Frame", {
        AutomaticSize = Enum.AutomaticSize.Y,
        Size = UDim2.new(1, 0, 0, 0),
        BackgroundColor3 = THEME.BgCard,
        BorderSizePixel = 0,
        Parent = InfoScroll,
    })
    corner(box, 4)
    stroke(box, THEME.Border)
    create("UIPadding", {
        PaddingTop = UDim.new(0, 5), PaddingBottom = UDim.new(0, 5),
        PaddingLeft = UDim.new(0, 8), PaddingRight = UDim.new(0, 8),
        Parent = box,
    })

    create("TextLabel", {
        Size = UDim2.new(1, 0, 0, 14),
        BackgroundTransparency = 1,
        Font = Enum.Font.GothamMedium,
        TextSize = 9,
        TextColor3 = THEME.TextDim,
        Text = string.upper(label),
        TextXAlignment = Enum.TextXAlignment.Left,
        Parent = box,
    })

    return create("TextLabel", {
        AutomaticSize = Enum.AutomaticSize.Y,
        Size = UDim2.new(1, 0, 0, 0),
        Position = UDim2.new(0, 0, 0, 14),
        BackgroundTransparency = 1,
        Font = Enum.Font.RobotoMono,
        TextSize = 10,
        TextColor3 = THEME.TextPrimary,
        Text = "--",
        TextWrapped = true,
        TextXAlignment = Enum.TextXAlignment.Left,
        Parent = box,
    })
end

local DiagName   = createDiagRow("Object Name")
local DiagClass  = createDiagRow("Asset Type / Class")
local DiagStatus = createDiagRow("Fetch Status")
local DiagId     = createDiagRow("Resource Content ID")
local DiagPath   = createDiagRow("Full Hierarchy Path")

local InfoActionRow = create("Frame", {
    Size = UDim2.new(1, 0, 0, 24),
    Position = UDim2.new(0, 0, 1, -24),
    BackgroundTransparency = 1,
    Parent = InfoPage,
})

local InfoRetryBtn = create("TextButton", {
    Size = UDim2.new(0.5, -4, 1, 0),
    BackgroundColor3 = THEME.BgCard,
    BorderSizePixel = 0,
    TextColor3 = THEME.Accent,
    Font = Enum.Font.GothamMedium,
    TextSize = 10,
    Text = "Retry Asset",
    Parent = InfoActionRow,
})
corner(InfoRetryBtn, 5)
stroke(InfoRetryBtn, THEME.Border)

local InfoCopyBtn = create("TextButton", {
    Size = UDim2.new(0.5, -4, 1, 0),
    Position = UDim2.new(0.5, 4, 0, 0),
    BackgroundColor3 = THEME.BgCard,
    BorderSizePixel = 0,
    TextColor3 = THEME.TextMuted,
    Font = Enum.Font.GothamMedium,
    TextSize = 10,
    Text = "Copy Full Report",
    Parent = InfoActionRow,
})
corner(InfoCopyBtn, 5)
stroke(InfoCopyBtn, THEME.Border)

local ResizeGrip = create("Frame", {
    Size = UDim2.new(0, 14, 0, 14),
    Position = UDim2.new(1, -14, 1, -14),
    BackgroundTransparency = 1,
    Active = true,
    ZIndex = 20,
    Parent = RootFrame,
})

for _, offset in ipairs({4, 7, 10}) do
    create("Frame", {
        Size = UDim2.new(0, offset, 0, 1),
        Position = UDim2.new(1, -offset, 1, -offset),
        BackgroundColor3 = THEME.Border,
        BorderSizePixel = 0,
        ZIndex = 21,
        Parent = ResizeGrip,
    })
end

local currentRecord: FailedRecord? = nil

local function updateUI()
    local safeTotal = math.max(1, state.totalInstances)
    local progress = math.clamp(state.processedInstances / safeTotal, 0, 1)
    local pct = math.floor(progress * 100)

    PercentText.Text = pct .. "%"
    CountText.Text = string.format("%d / %d assets", state.processedInstances, state.totalInstances)
    TabErrorsBtn.Text = string.format("Errors (%d)", #state.failed)
    TabErrorsBtn.TextColor3 = (#state.failed > 0) and THEME.Danger or THEME.TextMuted

    if state.isMinimized then
        TitleLabel.Text = pct .. "%"
    end

    TweenService:Create(ProgressBar, TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
        Size = UDim2.new(progress, 0, 1, 0),
    }):Play()
end

local function retrySingleAsset(errRecord: FailedRecord, actionBtn: TextButton?, cardFrame: Frame?)
    if actionBtn then
        actionBtn.Text = "..."
        actionBtn.TextColor3 = THEME.TextMuted
    end

    task.spawn(function()
        local startTime = os.clock()
        local targetToLoad: {Instance} = {}
        if errRecord.targetInstance and errRecord.targetInstance.Parent then
            table.insert(targetToLoad, errRecord.targetInstance)
        end

        local retrySucceeded = false
        local latestStatus = "Unknown"

        if #targetToLoad > 0 then
            ContentProvider:PreloadAsync(targetToLoad, function(_, status)
                latestStatus = tostring(status)
                if status == Enum.AssetFetchStatus.Success then
                    retrySucceeded = true
                end
            end)
        else
            latestStatus = "Instance destroyed"
        end

        local elapsedMs = math.floor((os.clock() - startTime) * 1000)

        if retrySucceeded then
            if actionBtn then
                actionBtn.Text = string.format("OK %dms", elapsedMs)
                actionBtn.TextColor3 = THEME.Success
            end
            if cardFrame then
                cardFrame.BackgroundColor3 = THEME.SuccessBg
                local s = cardFrame:FindFirstChildOfClass("UIStroke")
                if s then
                    s.Color = THEME.Success
                end
            end

            task.delay(1.2, function()
                for i, item in ipairs(state.failed) do
                    if item == errRecord or item.id == errRecord.id then
                        table.remove(state.failed, i)
                        break
                    end
                end
                state.failedSeen[errRecord.id] = nil
                state.recoveredCount += 1
                updateUI()
                if state.activeTab == "errors" then
                    renderErrors(SearchInput.Text)
                elseif state.activeTab == "info" then
                    switchTab("errors")
                end
            end)
        else
            errRecord.retries += 1
            errRecord.reason = string.format("%s (attempt %d)", latestStatus, errRecord.retries + 1)
            if actionBtn then
                actionBtn.Text = "Fail"
                actionBtn.TextColor3 = THEME.Danger
                task.delay(1.4, function()
                    actionBtn.Text = "Retry"
                    actionBtn.TextColor3 = THEME.Accent
                end)
            end
            if state.activeTab == "info" and currentRecord == errRecord then
                DiagStatus.Text = errRecord.reason
            end
            updateUI()
        end
    end)
end

function renderErrors(query: string?)
    for _, item in ipairs(ErrorScroll:GetChildren()) do
        if item:IsA("Frame") or item:IsA("TextLabel") then
            item:Destroy()
        end
    end

    local q = string.lower(query or "")
    local count = 0

    for idx, err in ipairs(state.failed) do
        local matches = (q == "")
            or string.find(string.lower(err.name), q, 1, true)
            or string.find(string.lower(err.reason), q, 1, true)
            or string.find(string.lower(err.fullName), q, 1, true)

        if matches then
            count += 1
            local card = create("Frame", {
                Name = "ErrorCard_" .. idx,
                Size = UDim2.new(1, 0, 0, 42),
                BackgroundColor3 = THEME.BgSecondary,
                BorderSizePixel = 0,
                Parent = ErrorScroll,
            })
            corner(card, 5)
            stroke(card, THEME.Border)

            create("TextLabel", {
                Size = UDim2.new(1, -155, 0, 16),
                Position = UDim2.new(0, 8, 0, 4),
                BackgroundTransparency = 1,
                Font = Enum.Font.RobotoMono,
                TextSize = 10,
                TextColor3 = THEME.TextPrimary,
                Text = err.name,
                TextTruncate = Enum.TextTruncate.AtEnd,
                TextXAlignment = Enum.TextXAlignment.Left,
                Parent = card,
            })

            create("TextLabel", {
                Size = UDim2.new(1, -155, 0, 16),
                Position = UDim2.new(0, 8, 0, 20),
                BackgroundTransparency = 1,
                Font = Enum.Font.Gotham,
                TextSize = 9,
                TextColor3 = THEME.Danger,
                Text = string.format("[%s] %s", err.assetType, err.reason),
                TextTruncate = Enum.TextTruncate.AtEnd,
                TextXAlignment = Enum.TextXAlignment.Left,
                Parent = card,
            })

            local btnHolder = create("Frame", {
                Size = UDim2.new(0, 146, 1, 0),
                Position = UDim2.new(1, -150, 0, 0),
                BackgroundTransparency = 1,
                Parent = card,
            })
            create("UIListLayout", {
                FillDirection = Enum.FillDirection.Horizontal,
                HorizontalAlignment = Enum.HorizontalAlignment.Right,
                VerticalAlignment = Enum.VerticalAlignment.Center,
                Padding = UDim.new(0, 4),
                Parent = btnHolder,
            })

            local infoBtn = create("TextButton", {
                Size = UDim2.new(0, 36, 0, 22),
                BackgroundColor3 = THEME.BgCard,
                BorderSizePixel = 0,
                TextColor3 = THEME.TextMuted,
                Font = Enum.Font.GothamMedium,
                TextSize = 9,
                Text = "Info",
                Parent = btnHolder,
            })
            corner(infoBtn, 4)

            local retryBtn = create("TextButton", {
                Size = UDim2.new(0, 52, 0, 22),
                BackgroundColor3 = THEME.BgCard,
                BorderSizePixel = 0,
                TextColor3 = THEME.Accent,
                Font = Enum.Font.GothamMedium,
                TextSize = 9,
                Text = "Retry",
                Parent = btnHolder,
            })
            corner(retryBtn, 4)

            local copyBtn = create("TextButton", {
                Size = UDim2.new(0, 40, 0, 22),
                BackgroundColor3 = THEME.BgCard,
                BorderSizePixel = 0,
                TextColor3 = THEME.TextMuted,
                Font = Enum.Font.GothamMedium,
                TextSize = 9,
                Text = "Copy",
                Parent = btnHolder,
            })
            corner(copyBtn, 4)

            infoBtn.MouseButton1Click:Connect(function()
                openDiagnostics(err)
            end)
            retryBtn.MouseButton1Click:Connect(function()
                retrySingleAsset(err, retryBtn, card)
            end)
            copyBtn.MouseButton1Click:Connect(function()
                if typeof(setclipboard) == "function" then
                    setclipboard(string.format("%s (%s): %s", err.fullName, err.assetType, err.reason))
                    copyBtn.Text = "OK"
                    task.delay(1, function() copyBtn.Text = "Copy" end)
                end
            end)
        end
    end

    if count == 0 then
        create("TextLabel", {
            Size = UDim2.new(1, 0, 0, 40),
            BackgroundTransparency = 1,
            Font = Enum.Font.Gotham,
            TextSize = 11,
            TextColor3 = THEME.TextDim,
            Text = (q == "") and "No errors recorded." or "No assets match search.",
            Parent = ErrorScroll,
        })
    end
end

function switchTab(tab: string)
    state.activeTab = tab
    MonitorPage.Visible = (tab == "monitor")
    ErrorsPage.Visible = (tab == "errors")
    InfoPage.Visible = (tab == "info")

    TabMonitorBtn.BackgroundColor3 = (tab == "monitor") and THEME.BgCard or THEME.BgMain
    TabMonitorBtn.BackgroundTransparency = (tab == "monitor") and 0 or 1
    TabMonitorBtn.TextColor3 = (tab == "monitor") and THEME.TextPrimary or THEME.TextMuted

    TabErrorsBtn.BackgroundColor3 = (tab == "errors") and THEME.BgCard or THEME.BgMain
    TabErrorsBtn.BackgroundTransparency = (tab == "errors") and 0 or 1
    TabErrorsBtn.TextColor3 = (tab == "errors") and THEME.TextPrimary or THEME.TextMuted

    if tab == "errors" then
        renderErrors(SearchInput.Text)
    end
end

function openDiagnostics(record: FailedRecord)
    currentRecord = record
    DiagName.Text = record.name
    DiagClass.Text = record.assetType
    DiagStatus.Text = record.reason
    DiagStatus.TextColor3 = THEME.Danger
    DiagId.Text = (record.contentId ~= "" and record.contentId) or "N/A (Builtin)"
    DiagPath.Text = record.fullName
    switchTab("info")
end

TabMonitorBtn.MouseButton1Click:Connect(function() switchTab("monitor") end)
TabErrorsBtn.MouseButton1Click:Connect(function() switchTab("errors") end)
InfoBackBtn.MouseButton1Click:Connect(function() switchTab("errors") end)

InfoCopyBtn.MouseButton1Click:Connect(function()
    if not currentRecord then return end
    local report = string.format("Object: %s\nClass: %s\nStatus: %s\nResource: %s\nPath: %s",
        currentRecord.name, currentRecord.assetType, currentRecord.reason, currentRecord.contentId, currentRecord.fullName)
    if typeof(setclipboard) == "function" then
        setclipboard(report)
        InfoCopyBtn.Text = "Copied!"
        task.delay(1, function() InfoCopyBtn.Text = "Copy Full Report" end)
    end
end)

InfoRetryBtn.MouseButton1Click:Connect(function()
    if currentRecord then
        retrySingleAsset(currentRecord, InfoRetryBtn, nil)
    end
end)

local searchDeb: thread? = nil
SearchInput:GetPropertyChangedSignal("Text"):Connect(function()
    if searchDeb then task.cancel(searchDeb) end
    searchDeb = task.delay(CONFIG.SearchDebounce, function()
        renderErrors(SearchInput.Text)
    end)
end)

RetryAllBtn.MouseButton1Click:Connect(function()
    if #state.failed == 0 then return end
    RetryAllBtn.Text = "Retrying..."

    task.spawn(function()
        local recovered = 0
        local toRetry: {Instance} = {}
        for _, item in ipairs(state.failed) do
            if item.targetInstance and item.targetInstance.Parent then
                table.insert(toRetry, item.targetInstance)
            end
        end

        if #toRetry > 0 then
            ContentProvider:PreloadAsync(toRetry, function(contentId, status)
                if status == Enum.AssetFetchStatus.Success then
                    recovered += 1
                    for i = #state.failed, 1, -1 do
                        local f = state.failed[i]
                        if f.contentId == contentId or (f.targetInstance and f.targetInstance.Name == contentId) then
                            state.failedSeen[f.id] = nil
                            table.remove(state.failed, i)
                        end
                    end
                end
            end)
        end

        state.recoveredCount += recovered
        RetryAllBtn.Text = string.format("+%d", recovered)
        updateUI()
        renderErrors(SearchInput.Text)
        task.delay(1.4, function() RetryAllBtn.Text = "Retry All" end)
    end)
end)

local isDragging, dragStart, frameStart = false, Vector3.zero, UDim2.new()
Header.InputBegan:Connect(function(input: InputObject)
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
        isDragging = true
        dragStart = input.Position
        frameStart = RootFrame.Position
        input.Changed:Connect(function()
            if input.UserInputState == Enum.UserInputState.End then
                isDragging = false
            end
        end)
    end
end)

local isResizing, resizeStart, startSize = false, Vector2.zero, Vector2.zero
ResizeGrip.InputBegan:Connect(function(input: InputObject)
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
        isResizing = true
        resizeStart = Vector2.new(input.Position.X, input.Position.Y)
        startSize = Vector2.new(RootFrame.AbsoluteSize.X, RootFrame.AbsoluteSize.Y)
        input.Changed:Connect(function()
            if input.UserInputState == Enum.UserInputState.End then
                isResizing = false
                if not state.isMinimized then
                    state.savedSize = RootFrame.Size
                end
            end
        end)
    end
end)

UserInputService.InputChanged:Connect(function(input: InputObject)
    if isDragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
        local delta = input.Position - dragStart
        RootFrame.Position = UDim2.new(frameStart.X.Scale, frameStart.X.Offset + delta.X, frameStart.Y.Scale, frameStart.Y.Offset + delta.Y)
    elseif isResizing and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
        local deltaX = input.Position.X - resizeStart.X
        local deltaY = input.Position.Y - resizeStart.Y
        local newW = math.clamp(startSize.X + deltaX, CONFIG.MinWidth, CONFIG.MaxWidth)
        local newH = math.clamp(startSize.Y + deltaY, CONFIG.MinHeight, CONFIG.MaxHeight)
        RootFrame.Size = UDim2.new(0, newW, 0, newH)
    end
end)

local function setMinimized(mini: boolean)
    state.isMinimized = mini
    if mini then
        state.savedSize = RootFrame.Size
        TweenService:Create(RootFrame, TweenInfo.new(CONFIG.AnimSpeed, Enum.EasingStyle.Quad), {
            Size = UDim2.new(0, 160, 0, 36)
        }):Play()

        TabNav.Visible = false
        MonitorPage.Visible = false
        ErrorsPage.Visible = false
        InfoPage.Visible = false
        ResizeGrip.Visible = false
        TitleLabel.Text = PercentText.Text
        MinBtn.Text = "+"
    else
        TweenService:Create(RootFrame, TweenInfo.new(CONFIG.AnimSpeed, Enum.EasingStyle.Quad), {
            Size = state.savedSize
        }):Play()

        TabNav.Visible = true
        ResizeGrip.Visible = true
        switchTab(state.activeTab)
        TitleLabel.Text = "asset.loader"
        MinBtn.Text = "-"
    end
end

MinBtn.MouseButton1Click:Connect(function()
    setMinimized(not state.isMinimized)
end)

UserInputService.InputBegan:Connect(function(input: InputObject, gp: boolean)
    if not gp and input.KeyCode == Enum.KeyCode.L and UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
        RootFrame.Visible = not RootFrame.Visible
    end
end)

local frameCount = 0
local lastSample = os.clock()

RunService.RenderStepped:Connect(function()
    frameCount += 1
    local now = os.clock()
    local dt = now - lastSample

    if dt >= 0.65 then
        local fps = math.floor(frameCount / dt)
        frameCount = 0
        lastSample = now

        ChipFps.Text = string.format("FPS %d", fps)
        ChipFps.TextColor3 = (fps >= 45 and THEME.TextMuted) or THEME.Danger

        local ok, ping = pcall(function()
            return math.floor(Stats.Network.ServerStatsItem["Data Ping"]:GetValue())
        end)
        if ok then
            ChipPing.Text = string.format("%dms", ping)
        end

        if state.isRunning and not state.isComplete then
            state.elapsedTime = os.clock() - state.startTime
            ChipTime.Text = formatClock(state.elapsedTime)

            local speed = (state.elapsedTime > 0) and (state.processedInstances / state.elapsedTime) or 0
            state.speed = speed
            ChipSpeed.Text = string.format("%.0f/s", speed)

            local remain = math.max(0, state.totalInstances - state.processedInstances)
            local eta = (speed > 0) and math.ceil(remain / speed) or 0
            ChipEta.Text = (eta > 0 and eta < 999) and string.format("ETA %ds", eta) or "ETA --"
        end
    end
end)

local assetQueue: {Instance} = {}
local isWorking = false

local function processBatch(batch: {Instance})
    if #batch == 0 then return end
    local leader = batch[1]
    if leader and leader.Parent then
        CurrentPath.Text = formatPath(leader)
        CurrentMeta.Text = string.format("Class: %s | Batch: %d (%d files)", getAssetType(leader), #batch, state.totalFiles)
    end

    ContentProvider:PreloadAsync(batch, function(contentId, fetchStatus)
        state.totalFiles += 1
        if fetchStatus ~= Enum.AssetFetchStatus.Success then
            local idKey = tostring(contentId)
            if not state.failedSeen[idKey] then
                state.failedSeen[idKey] = true
                local foundInst: Instance? = nil
                for _, cand in ipairs(batch) do
                    if cand:GetFullName() == contentId or cand.Name == contentId then
                        foundInst = cand
                        break
                    end
                end
                local finalInst = foundInst or leader

                table.insert(state.failed, {
                    id = idKey,
                    name = finalInst and finalInst.Name or tostring(contentId),
                    fullName = finalInst and finalInst:GetFullName() or tostring(contentId),
                    assetType = finalInst and getAssetType(finalInst) or "Asset",
                    contentId = tostring(contentId),
                    targetInstance = finalInst,
                    reason = tostring(fetchStatus),
                    retries = 0,
                })
            end
        end
    end)

    state.processedInstances += #batch
    updateUI()
end

local function runWorker()
    if isWorking then return end
    isWorking = true

    task.spawn(function()
        while #assetQueue > 0 do
            local batch: {Instance} = {}
            for _ = 1, math.min(CONFIG.BatchSize, #assetQueue) do
                local item = table.remove(assetQueue, 1)
                if item then
                    table.insert(batch, item)
                end
            end
            if #batch > 0 then
                processBatch(batch)
            end
            task.wait()
        end

        isWorking = false

        if state.processedInstances >= state.totalInstances and not state.isComplete then
            state.isComplete = true
            state.isRunning = false
            StatusDot.BackgroundColor3 = THEME.Success
            CurrentPath.Text = "ALL ASSETS VERIFIED"
            CurrentMeta.Text = string.format("Done in %s (%d files, %d failed)", formatClock(state.elapsedTime), state.totalFiles, #state.failed)
            ChipEta.Text = "DONE"
            updateUI()
            if state.activeTab == "errors" then
                renderErrors(SearchInput.Text)
            end
        end
    end)
end

local function enqueue(items: {Instance})
    local added = 0
    for _, item in ipairs(items) do
        local id = item:GetFullName()
        if not _G.TrackerLoadedAssetIds[id] then
            _G.TrackerLoadedAssetIds[id] = true
            table.insert(assetQueue, item)
            added += 1
        end
    end

    if added > 0 then
        state.totalInstances += added
        state.isComplete = false
        StatusDot.BackgroundColor3 = THEME.Accent
        updateUI()
        runWorker()
    end
end

local pendingStream: {Instance} = {}
local streamDebounce: thread? = nil

local function onDescendant(inst: Instance)
    if isTrackable(inst) then
        table.insert(pendingStream, inst)
        if not streamDebounce then
            streamDebounce = task.delay(1.2, function()
                local toAdd = pendingStream
                pendingStream = {}
                streamDebounce = nil
                enqueue(toAdd)
            end)
        end
    end
end

workspace.DescendantAdded:Connect(onDescendant)
ReplicatedStorage.DescendantAdded:Connect(onDescendant)
local pGui = LocalPlayer:FindFirstChild("PlayerGui")
if pGui then
    pGui.DescendantAdded:Connect(onDescendant)
end

local function bootstrap()
    state.startTime = os.clock()
    state.isRunning = true
    CurrentPath.Text = "INDEXING DOMAIN ROOTS..."

    local roots: {Instance?} = {
        workspace, ReplicatedStorage, ReplicatedFirst, Lighting,
        MaterialService, SoundService, StarterPack, LocalPlayer:FindFirstChild("PlayerGui")
    }

    local found: {Instance} = {}
    local seen = {}

    for _, r in ipairs(roots) do
        if r then
            for _, d in ipairs(r:GetDescendants()) do
                if isTrackable(d) and not seen[d] then
                    seen[d] = true
                    table.insert(found, d)
                end
            end
        end
    end

    if #found == 0 then
        state.isComplete = true
        state.isRunning = false
        StatusDot.BackgroundColor3 = THEME.Success
        CurrentPath.Text = "NO ASSETS TO LOAD"
        CurrentMeta.Text = "0 items in memory"
        updateUI()
        return
    end

    enqueue(found)
end

bootstrap()

Features & Information

game taking ages to load? wanna see what’s loading right now? this script lets u do that
#Universal

Community Comments (1)

voltexvoltexApr 10, 2026

one year ago huh

More Scripts for Universal Scripts