-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] -- LocalScript (StarterPlayerScripts or StarterGui) -- Item List UI for 99 Nights in the Forest local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") -- ================= CONFIG ================= local TOGGLE_KEY = Enum.KeyCode.U local NEARBY_RANGE = 80 local NEARBY_CHECK_RATE = 0.15 -- ========================================== local guiVisible = true local nearbyEnabled = false local itemGroups = {} -- [groupName] = {Model, ...} local revealedGroups = {} -- [groupName] = true local activeMarkers = {} -- [Model] = BillboardGui local lastNearbyCheck = 0 local itemsFolder = nil local dragging = false local dragStart, frameStart -- ============ Helpers ============ local function getGroupName(obj) local name = obj.Name if string.find(string.lower(name), "chest") then return "Chest" end return name end local function clearMarker(inst) local marker = activeMarkers[inst] if marker then marker:Destroy() activeMarkers[inst] = nil end end local function clearGroupMarkers(groupName) local group = itemGroups[groupName] if not group then return end for _, inst in ipairs(group) do clearMarker(inst) end end local function getItemPosition(inst) if not inst or not inst.Parent then return nil end if inst:IsA("Model") then return inst:GetPivot().Position end return nil end local function setMarkerColor(inst, color) local marker = activeMarkers[inst] if marker then local label = marker:FindFirstChildOfClass("TextLabel") if label then label.TextColor3 = color end end end local function createMarker(inst, text, color) if not inst or not inst.Parent then return end clearMarker(inst) -- Prefer PrimaryPart, otherwise any BasePart deep in the model local adornee = inst.PrimaryPart if not adornee then adornee = inst:FindFirstChildWhichIsA("BasePart", true) end if not adornee then return end local billboard = Instance.new("BillboardGui") billboard.Name = "ItemMarker" billboard.Adornee = adornee billboard.Size = UDim2.new(0, 150, 0, 30) billboard.StudsOffset = Vector3.new(0, 3.2, 0) billboard.AlwaysOnTop = true billboard.MaxDistance = 600 billboard.LightInfluence = 0 billboard.Parent = playerGui local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 1, 0) label.BackgroundTransparency = 1 label.BorderSizePixel = 0 label.Text = text label.TextColor3 = color or Color3.fromRGB(255, 255, 255) label.TextSize = 13 label.Font = Enum.Font.GothamBold label.TextStrokeTransparency = 0.35 label.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) label.Parent = billboard activeMarkers[inst] = billboard end local function isValidItem(obj) return obj:IsA("Model") and (obj.PrimaryPart or obj:FindFirstChildWhichIsA("BasePart", true)) end -- ============ Item Management ============ local function rebuildGroups() local existingNames = {} for name in pairs(itemGroups) do existingNames[name] = true end table.clear(itemGroups) if itemsFolder then for _, child in ipairs(itemsFolder:GetChildren()) do if isValidItem(child) then local groupName = getGroupName(child) if not itemGroups[groupName] then itemGroups[groupName] = {} end table.insert(itemGroups[groupName], child) end end end -- Keep previously known empty groups for name in pairs(existingNames) do if not itemGroups[name] then itemGroups[name] = {} end end end -- ============ UI ============ local screenGui = Instance.new("ScreenGui") screenGui.Name = "ItemListUI" screenGui.ResetOnSpawn = false screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling screenGui.Parent = playerGui local mainFrame = Instance.new("Frame") mainFrame.Name = "Main" mainFrame.Size = UDim2.new(0, 270, 0, 400) mainFrame.Position = UDim2.new(0, 18, 0.5, -200) mainFrame.BackgroundColor3 = Color3.fromRGB(22, 24, 28) mainFrame.BorderSizePixel = 0 mainFrame.Active = true mainFrame.Parent = screenGui Instance.new("UICorner", mainFrame).CornerRadius = UDim.new(0, 10) local stroke = Instance.new("UIStroke", mainFrame) stroke.Color = Color3.fromRGB(70, 70, 80) stroke.Thickness = 1.5 local titleBar = Instance.new("Frame") titleBar.Size = UDim2.new(1, 0, 0, 36) titleBar.BackgroundColor3 = Color3.fromRGB(32, 34, 40) titleBar.BorderSizePixel = 0 titleBar.Parent = mainFrame Instance.new("UICorner", titleBar).CornerRadius = UDim.new(0, 10) local titleFix = Instance.new("Frame") titleFix.Size = UDim2.new(1, 0, 0, 14) titleFix.Position = UDim2.new(0, 0, 1, -14) titleFix.BackgroundColor3 = Color3.fromRGB(32, 34, 40) titleFix.BorderSizePixel = 0 titleFix.Parent = titleBar local titleLabel = Instance.new("TextLabel") titleLabel.Size = UDim2.new(1, -70, 1, 0) titleLabel.Position = UDim2.new(0, 12, 0, 0) titleLabel.BackgroundTransparency = 1 titleLabel.Text = "Items [U]" titleLabel.TextColor3 = Color3.fromRGB(255, 215, 90) titleLabel.TextSize = 16 titleLabel.Font = Enum.Font.GothamBold titleLabel.TextXAlignment = Enum.TextXAlignment.Left titleLabel.Parent = titleBar local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 28, 0, 28) closeBtn.Position = UDim2.new(1, -32, 0, 4) closeBtn.BackgroundColor3 = Color3.fromRGB(70, 30, 30) closeBtn.Text = "X" closeBtn.TextColor3 = Color3.fromRGB(255, 170, 170) closeBtn.TextSize = 14 closeBtn.Font = Enum.Font.GothamBold closeBtn.Parent = titleBar Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0, 6) closeBtn.MouseButton1Click:Connect(function() guiVisible = false mainFrame.Visible = false end) local scroll = Instance.new("ScrollingFrame") scroll.Name = "List" scroll.Size = UDim2.new(1, -12, 1, -48) scroll.Position = UDim2.new(0, 6, 0, 42) scroll.BackgroundTransparency = 1 scroll.BorderSizePixel = 0 scroll.ScrollBarThickness = 5 scroll.ScrollBarImageColor3 = Color3.fromRGB(110, 110, 120) scroll.CanvasSize = UDim2.new(0, 0, 0, 0) scroll.Parent = mainFrame local statusLabel = Instance.new("TextLabel") statusLabel.Size = UDim2.new(1, -8, 0, 30) statusLabel.Position = UDim2.new(0, 4, 0, 40) statusLabel.BackgroundTransparency = 1 statusLabel.Text = "Waiting for Items..." statusLabel.TextColor3 = Color3.fromRGB(160, 160, 170) statusLabel.TextSize = 13 statusLabel.Font = Enum.Font.Gotham statusLabel.Visible = false statusLabel.Parent = scroll local nearbyBtn = Instance.new("TextButton") nearbyBtn.Name = "NearbyItems" nearbyBtn.Size = UDim2.new(1, -8, 0, 32) nearbyBtn.Position = UDim2.new(0, 4, 0, 0) nearbyBtn.BackgroundColor3 = Color3.fromRGB(40, 55, 40) nearbyBtn.BorderSizePixel = 0 nearbyBtn.Text = "Nearby Items [OFF]" nearbyBtn.TextColor3 = Color3.fromRGB(170, 255, 170) nearbyBtn.TextSize = 14 nearbyBtn.Font = Enum.Font.GothamBold nearbyBtn.Parent = scroll Instance.new("UICorner", nearbyBtn).CornerRadius = UDim.new(0, 6) nearbyBtn.MouseButton1Click:Connect(function() nearbyEnabled = not nearbyEnabled if nearbyEnabled then nearbyBtn.Text = "Nearby Items [ON]" nearbyBtn.BackgroundColor3 = Color3.fromRGB(35, 85, 45) nearbyBtn.TextColor3 = Color3.fromRGB(140, 255, 140) else nearbyBtn.Text = "Nearby Items [OFF]" nearbyBtn.BackgroundColor3 = Color3.fromRGB(40, 55, 40) nearbyBtn.TextColor3 = Color3.fromRGB(170, 255, 170) -- Reset colors of manually revealed items back to white for inst, _ in pairs(activeMarkers) do local groupName = getGroupName(inst) if revealedGroups[groupName] then setMarkerColor(inst, Color3.fromRGB(255, 255, 255)) else clearMarker(inst) end end end end) -- ============ List Building ============ local function rebuildList() for _, child in ipairs(scroll:GetChildren()) do if child:IsA("TextButton") and child ~= nearbyBtn then child:Destroy() end end local names = {} for name in pairs(itemGroups) do table.insert(names, name) end for name in pairs(revealedGroups) do if not itemGroups[name] then itemGroups[name] = {} table.insert(names, name) end end table.sort(names) if #names == 0 then statusLabel.Visible = true statusLabel.Text = itemsFolder and "No items found" or "Waiting for Items folder..." scroll.CanvasSize = UDim2.new(0, 0, 0, 80) return end statusLabel.Visible = false local y = 36 for _, name in ipairs(names) do local group = itemGroups[name] or {} local count = #group local isRevealed = revealedGroups[name] == true local btn = Instance.new("TextButton") btn.Name = name btn.Size = UDim2.new(1, -8, 0, 32) btn.Position = UDim2.new(0, 4, 0, y) btn.BorderSizePixel = 0 btn.Text = string.format("%s (%d)%s", name, count, isRevealed and " [ON]" or "") btn.TextSize = 14 btn.Font = Enum.Font.Gotham btn.AutoButtonColor = true btn.Parent = scroll Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 6) if isRevealed then btn.BackgroundColor3 = Color3.fromRGB(55, 70, 40) btn.TextColor3 = Color3.fromRGB(200, 255, 160) else btn.BackgroundColor3 = Color3.fromRGB(38, 40, 48) btn.TextColor3 = Color3.fromRGB(225, 225, 230) end btn.MouseButton1Click:Connect(function() if revealedGroups[name] then revealedGroups[name] = nil clearGroupMarkers(name) else revealedGroups[name] = true local currentGroup = itemGroups[name] if currentGroup then for _, inst in ipairs(currentGroup) do if inst and inst.Parent then createMarker(inst, name, Color3.fromRGB(255, 255, 255)) end end end end rebuildList() end) y += 36 end scroll.CanvasSize = UDim2.new(0, 0, 0, y + 10) end -- ============ Live Updates ============ local function onItemAdded(item) if not isValidItem(item) then return end local groupName = getGroupName(item) if not itemGroups[groupName] then itemGroups[groupName] = {} end table.insert(itemGroups[groupName], item) if revealedGroups[groupName] then createMarker(item, groupName, Color3.fromRGB(255, 255, 255)) end rebuildList() end local function onItemRemoved(item) local groupName = getGroupName(item) local group = itemGroups[groupName] if group then for i = #group, 1, -1 do if group[i] == item then table.remove(group, i) break end end -- Keep empty groups + revealed state end clearMarker(item) rebuildList() end local function setupItemsFolder() itemsFolder = workspace:WaitForChild("Items", 30) if not itemsFolder then statusLabel.Visible = true statusLabel.Text = "Items folder not found!" return end rebuildGroups() rebuildList() itemsFolder.ChildAdded:Connect(onItemAdded) itemsFolder.ChildRemoved:Connect(onItemRemoved) end -- ============ Dragging ============ titleBar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position frameStart = mainFrame.Position end end) titleBar.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end end) UserInputService.InputChanged:Connect(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - dragStart mainFrame.Position = UDim2.new( frameStart.X.Scale, frameStart.X.Offset + delta.X, frameStart.Y.Scale, frameStart.Y.Offset + delta.Y ) end end) -- ============ Hotkey ============ UserInputService.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == TOGGLE_KEY then guiVisible = not guiVisible mainFrame.Visible = guiVisible end end) -- ============ Nearby + Yellow Logic ============ RunService.Heartbeat:Connect(function() local now = os.clock() if now - lastNearbyCheck < NEARBY_CHECK_RATE then return end lastNearbyCheck = now local char = player.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if not hrp then return end local rootPos = hrp.Position for groupName, group in pairs(itemGroups) do local isManuallyRevealed = revealedGroups[groupName] == true for _, inst in ipairs(group) do if inst and inst.Parent then local pos = getItemPosition(inst) if pos then local dist = (pos - rootPos).Magnitude local inRange = dist <= NEARBY_RANGE if isManuallyRevealed then -- Always show the marker if not activeMarkers[inst] then createMarker(inst, groupName, Color3.fromRGB(255, 255, 255)) end -- Yellow only when nearby is also ON and item is in range if nearbyEnabled and inRange then setMarkerColor(inst, Color3.fromRGB(255, 220, 50)) -- yellow else setMarkerColor(inst, Color3.fromRGB(255, 255, 255)) -- white end else -- Normal nearby behavior if nearbyEnabled and inRange then if not activeMarkers[inst] then createMarker(inst, groupName, Color3.fromRGB(255, 255, 255)) end else clearMarker(inst) end end end end end end end) -- Start task.spawn(setupItemsFolder) print("[ItemListUI] Loaded • Press U to toggle • Drag title bar to move")