-- ---- CONFIG SAVING ----
pcall(function()
if cfg.ConfigurationSaving then
CFileName = cfg.ConfigurationSaving.FileName or tostring(game.PlaceId)
CEnabled = cfg.ConfigurationSaving.Enabled ~= false
if CEnabled then safeMakeFolder(cfg.ConfigurationSaving.FolderName or CFG_FOLDER) end
end
end)
-- ============================================================
-- KEY SYSTEM
-- ============================================================
if cfg.KeySystem and cfg.KeySettings then
local KS = cfg.KeySettings
if typeof(KS.Key) == "string" then KS.Key = {KS.Key} end
if KS.GrabKeyFromSite then
for i, k in ipairs(KS.Key) do
pcall(function()
KS.Key[i] = tostring(game:HttpGet(k)):gsub("[\n\r ]","")
end)
end
end
KS.FileName = KS.FileName or "NoirX_Key"
local keyPath = FOLDER.."/Key System"
safeMakeFolder(keyPath)
local passthrough = false
pcall(function()
local saved = readfile(keyPath.."/"..KS.FileName..CFG_EXT)
for _, mk in ipairs(KS.Key) do
if saved:find(mk, 1, true) then passthrough = true end
end
end)
if not passthrough then
-- Key UI
local KeyRoot = New("ScreenGui",{Name="NoirX_Key",ResetOnSpawn=false,IgnoreGuiInset=true,ZIndexBehavior=Enum.ZIndexBehavior.Sibling},CoreGui)
local kBG = New("Frame",{
Size=UDim2.new(0,440,0,220),
Position=UDim2.new(0.5,-220,0.5,-110),
BackgroundColor3=T.BG,
BackgroundTransparency=0,
BorderSizePixel=0,
},KeyRoot)
Corner(14,kBG)
Stroke(T.BorderHi,0.8,kBG)
-- accent bar top
New("Frame",{Size=UDim2.new(1,0,0,3),BackgroundColor3=T.Accent,BorderSizePixel=0},kBG)
Corner(14, kBG:FindFirstChildOfClass("Frame"))
New("TextLabel",{
Size=UDim2.new(1,0,0,28),Position=UDim2.new(0,0,0,14),
BackgroundTransparency=1,Text=KS.Title or cfg.Name or "NoirX Tz",
TextColor3=T.Text,TextSize=16,Font=Enum.Font.GothamBold,
TextXAlignment=Enum.TextXAlignment.Center,
},kBG)
New("TextLabel",{
Size=UDim2.new(1,0,0,20),Position=UDim2.new(0,0,0,42),
BackgroundTransparency=1,Text=KS.Subtitle or "Key System",
TextColor3=T.TextDim,TextSize=11,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Center,
},kBG)
New("TextLabel",{
Size=UDim2.new(1,-40,0,16),Position=UDim2.new(0,20,0,70),
BackgroundTransparency=1,Text=KS.Note or "Enter the key below.",
TextColor3=T.TextDim,TextSize=10,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Center,TextWrapped=true,
},kBG)
local kInput = New("TextBox",{
Size=UDim2.new(1,-40,0,36),Position=UDim2.new(0,20,0,100),
BackgroundColor3=T.Surface,BorderSizePixel=0,
PlaceholderText="paste key here...",PlaceholderColor3=T.TextDim,
Text="",TextColor3=T.Text,TextSize=12,Font=Enum.Font.Gotham,
ClearTextOnFocus=false,
},kBG)
Corner(8,kInput)
Stroke(T.BorderHi,0.7,kInput)
Pad(10,10,0,0,kInput)
local kStatus = New("TextLabel",{
Size=UDim2.new(1,-40,0,16),Position=UDim2.new(0,20,0,148),
BackgroundTransparency=1,Text="",
TextColor3=T.Error,TextSize=10,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Center,
},kBG)
local kBtn = New("TextButton",{
Size=UDim2.new(1,-40,0,36),Position=UDim2.new(0,20,0,172),
BackgroundColor3=T.Accent,BorderSizePixel=0,
Text="UNLOCK",TextColor3=T.White,TextSize=12,Font=Enum.Font.GothamBold,
},kBG)
Corner(8,kBtn)
local attempts = 5
kBtn.MouseButton1Click:Connect(function()
local found = false
local foundKey = ""
for _, mk in ipairs(KS.Key) do
if kInput.Text:find(mk, 1, true) then
found = true; foundKey = mk
end
end
if found then
if KS.SaveKey then
pcall(writefile, keyPath.."/"..KS.FileName..CFG_EXT, foundKey)
end
tw(kBG, 0.3, {BackgroundTransparency=1})
task.wait(0.35)
KeyRoot:Destroy()
passthrough = true
else
attempts = attempts - 1
if attempts <= 0 then
LocalPlayer:Kick("NoirX: No attempts remaining.")
end
kStatus.Text = "Invalid key. "..attempts.." attempt(s) left."
tw(kInput, 0.1, {BackgroundColor3=Color3.fromRGB(80,20,20)})
task.wait(0.5)
tw(kInput, 0.3, {BackgroundColor3=T.Surface})
end
end)
repeat task.wait() until passthrough
end
end
-- ============================================================
-- MAIN WINDOW FRAME
-- ============================================================
local Main = New("Frame",{
Name = "NoirX_Main",
Size = UDim2.new(0, WIN_W, 0, WIN_H),
Position = UDim2.new(0.5, -WIN_W/2, 0.5, -WIN_H/2),
BackgroundColor3= T.BG,
BorderSizePixel = 0,
ClipsDescendants= false,
}, Root)
Corner(14, Main)
Stroke(T.Border, 0.8, Main)
-- shadow
New("ImageLabel",{
Size=UDim2.new(1,40,1,40),Position=UDim2.new(0,-20,0,-20),
BackgroundTransparency=1,
Image="rbxassetid://5028857084",
ImageColor3=T.Black,ImageTransparency=0.6,
ZIndex=0,ScaleType=Enum.ScaleType.Slice,SliceCenter=Rect.new(24,24,276,276),
},Main)
-- accent line top
local accentBar = New("Frame",{
Size=UDim2.new(1,0,0,2),
BackgroundColor3=T.Accent,
BorderSizePixel=0,
ZIndex=10,
},Main)
Corner(14,accentBar)
-- ============================================================
-- DRAG
-- ============================================================
do
local dragging, dragStart, startPos = false
Main.InputBegan:Connect(function(i)
if i.UserInputType == Enum.UserInputType.MouseButton1 then
dragging=true; dragStart=i.Position; startPos=Main.Position
end
end)
Main.InputEnded:Connect(function(i)
if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging=false end
end)
UIS.InputChanged:Connect(function(i)
if dragging and i.UserInputType==Enum.UserInputType.MouseMovement then
local d = i.Position - dragStart
tw(Main, 0.12, {Position=UDim2.new(startPos.X.Scale,startPos.X.Offset+d.X,startPos.Y.Scale,startPos.Y.Offset+d.Y)})
end
end)
end
-- ============================================================
-- SIDEBAR
-- ============================================================
local Sidebar = New("Frame",{
Size = UDim2.new(0, SIDE_W, 1, 0),
BackgroundColor3= T.BGDeep,
BorderSizePixel = 0,
ZIndex = 5,
ClipsDescendants= true,
}, Main)
Corner(14, Sidebar)
-- fix right corners
New("Frame",{
Size=UDim2.new(0,14,1,0),Position=UDim2.new(1,-14,0,0),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,ZIndex=5,
},Sidebar)
-- logo / title area
local SideTop = New("Frame",{
Size=UDim2.new(1,0,0,56),
BackgroundTransparency=1,
ZIndex=6,
},Sidebar)
New("TextLabel",{
Size=UDim2.new(1,-16,0,20),Position=UDim2.new(0,12,0,10),
BackgroundTransparency=1,
Text="NoirX Tz",
TextColor3=T.Text,TextSize=13,Font=Enum.Font.GothamBold,
TextXAlignment=Enum.TextXAlignment.Left,ZIndex=7,
},SideTop)
New("TextLabel",{
Size=UDim2.new(1,-16,0,14),Position=UDim2.new(0,12,0,30),
BackgroundTransparency=1,
Text=cfg.Name or "Script Hub",
TextColor3=T.TextDim,TextSize=9,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Left,ZIndex=7,
},SideTop)
-- divider
New("Frame",{
Size=UDim2.new(1,-24,0,1),Position=UDim2.new(0,12,0,56),
BackgroundColor3=T.Border,BorderSizePixel=0,ZIndex=6,
},Sidebar)
-- tab buttons list
local TabBtnList = New("ScrollingFrame",{
Size=UDim2.new(1,0,1,-64),Position=UDim2.new(0,0,0,62),
BackgroundTransparency=1,BorderSizePixel=0,
ScrollBarThickness=0,CanvasSize=UDim2.new(0,0,0,0),
AutomaticCanvasSize=Enum.AutomaticSize.Y,
ZIndex=6,
},Sidebar)
ListLayout(TabBtnList, 4)
Pad(8,8,6,6,TabBtnList)
-- ============================================================
-- CONTENT AREA
-- ============================================================
local ContentArea = New("Frame",{
Size = UDim2.new(1,-SIDE_W,1,0),
Position = UDim2.new(0,SIDE_W,0,0),
BackgroundTransparency=1,
ZIndex = 5,
ClipsDescendants= true,
}, Main)
-- topbar
local Topbar = New("Frame",{
Size=UDim2.new(1,0,0,44),
BackgroundTransparency=1,
ZIndex=6,
},ContentArea)
local WinTitle = New("TextLabel",{
Size=UDim2.new(1,-80,1,0),Position=UDim2.new(0,16,0,0),
BackgroundTransparency=1,
Text=cfg.Name or "NoirX",
TextColor3=T.Text,TextSize=13,Font=Enum.Font.GothamBold,
TextXAlignment=Enum.TextXAlignment.Left,ZIndex=7,
},Topbar)
-- close / minimise buttons
local function mkTopBtn(xOff, color, symbol, cb)
local b = New("TextButton",{
Size=UDim2.new(0,22,0,22),
Position=UDim2.new(1,-xOff,0.5,-11),
BackgroundColor3=color,
BorderSizePixel=0,
Text=symbol,TextColor3=T.White,TextSize=10,Font=Enum.Font.GothamBold,
ZIndex=8,
},Topbar)
Corner(11,b)
b.MouseEnter:Connect(function() tw(b,0.1,{BackgroundColor3=color:Lerp(T.White,0.2)}) end)
b.MouseLeave:Connect(function() tw(b,0.1,{BackgroundColor3=color}) end)
b.MouseButton1Click:Connect(cb)
return b
end
local minimised = false
local hidden = false
mkTopBtn(28, T.Error, "×", function()
tw(Main,0.25,{Size=UDim2.new(0,WIN_W,0,1),BackgroundTransparency=1})
task.wait(0.28)
Root:Destroy()
end)
local minBtn = mkTopBtn(56, T.Warning, "–", function()
if minimised then
minimised = false
tw(Main,0.3,{Size=UDim2.new(0,WIN_W,0,WIN_H)})
ContentArea.Visible = true
else
minimised = true
ContentArea.Visible = false
tw(Main,0.3,{Size=UDim2.new(0,WIN_W,0,44)})
end
end)
-- topbar divider
New("Frame",{
Size=UDim2.new(1,0,0,1),Position=UDim2.new(0,0,1,-1),
BackgroundColor3=T.Border,BorderSizePixel=0,ZIndex=6,
},Topbar)
-- page container
local Pages = New("Frame",{
Size=UDim2.new(1,0,1,-44),Position=UDim2.new(0,0,0,44),
BackgroundTransparency=1,ClipsDescendants=true,ZIndex=5,
},ContentArea)
-- ============================================================
-- KEYBIND HIDE (K)
-- ============================================================
UIS.InputBegan:Connect(function(input, processed)
if processed then return end
if UIS:GetFocusedTextBox() then return end
if input.KeyCode == Enum.KeyCode.K then
if hidden then
hidden = false
Main.Visible = true
tw(Main,0.3,{BackgroundTransparency=0})
NoirX:Notify({Title="Interface Shown", Content="Press K to hide again.", Duration=3})
else
hidden = true
NoirX:Notify({Title="Interface Hidden", Content="Press K to show again.", Duration=3})
task.wait(0.1)
tw(Main,0.2,{BackgroundTransparency=1})
task.wait(0.25)
Main.Visible = false
end
end
end)
-- ============================================================
-- WINDOW OBJECT
-- ============================================================
local Window = {}
local firstTab = true
local currentPage = nil
-- ============================================================
-- CREATE TAB
-- ============================================================
function Window:CreateTab(name, image)
-- Page
local Page = New("ScrollingFrame",{
Name=name,
Size=UDim2.new(1,-10,1,-10),Position=UDim2.new(0,5,0,5),
BackgroundTransparency=1,BorderSizePixel=0,
ScrollBarThickness=2,ScrollBarImageColor3=T.TextDim,
CanvasSize=UDim2.new(0,0,0,0),AutomaticCanvasSize=Enum.AutomaticSize.Y,
Visible=false,ZIndex=6,
},Pages)
ListLayout(Page, 6)
Pad(8,8,6,8,Page)
-- Sidebar Button
local TabBtn = New("TextButton",{
Name=name,
Size=UDim2.new(1,0,0,34),
BackgroundColor3=T.Surface,
BackgroundTransparency=1,
BorderSizePixel=0,
Text="",
ZIndex=7,
},TabBtnList)
Corner(8,TabBtn)
local tabIcon = New("ImageLabel",{
Size=UDim2.new(0,16,0,16),
Position=UDim2.new(0,10,0.5,-8),
BackgroundTransparency=1,
Image=image and ("rbxassetid://"..tostring(image)) or "rbxassetid://3926305904",
ImageColor3=T.TextDim,ZIndex=8,
},TabBtn)
local tabLbl = New("TextLabel",{
Size=UDim2.new(1,-36,1,0),
Position=UDim2.new(0,32,0,0),
BackgroundTransparency=1,
Text=name,
TextColor3=T.TextDim,TextSize=11,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Left,ZIndex=8,
},TabBtn)
-- indicator
local indicator = New("Frame",{
Size=UDim2.new(0,3,0.6,0),
Position=UDim2.new(0,-2,0.2,0),
BackgroundColor3=T.Accent,
BorderSizePixel=0,
BackgroundTransparency=1,
ZIndex=9,
},TabBtn)
Corner(3,indicator)
local function selectTab()
-- hide all
for _, p in ipairs(Pages:GetChildren()) do
if p:IsA("ScrollingFrame") then p.Visible = false end
end
-- deselect all btns
for _, b in ipairs(TabBtnList:GetChildren()) do
if b:IsA("TextButton") then
tw(b, 0.2, {BackgroundTransparency=1})
local ic = b:FindFirstChildOfClass("ImageLabel")
local lb = b:FindFirstChildOfClass("TextLabel")
local ind= b:FindFirstChildOfClass("Frame")
if ic then tw(ic,0.2,{ImageColor3=T.TextDim}) end
if lb then tw(lb,0.2,{TextColor3=T.TextDim, Font=Enum.Font.Gotham}) end
if ind then tw(ind,0.2,{BackgroundTransparency=1}) end
end
end
-- select this
Page.Visible = true
tw(TabBtn,0.2,{BackgroundTransparency=0.7,BackgroundColor3=T.AccentDim})
tw(tabIcon,0.2,{ImageColor3=T.White})
tw(tabLbl,0.2,{TextColor3=T.White})
tabLbl.Font = Enum.Font.GothamBold
tw(indicator,0.2,{BackgroundTransparency=0})
currentPage = Page
end
TabBtn.MouseButton1Click:Connect(selectTab)
TabBtn.MouseEnter:Connect(function()
if Page.Visible then return end
tw(TabBtn,0.15,{BackgroundTransparency=0.85})
end)
TabBtn.MouseLeave:Connect(function()
if Page.Visible then return end
tw(TabBtn,0.15,{BackgroundTransparency=1})
end)
if firstTab then
firstTab = false
selectTab()
end
-- ============================================================
-- ELEMENT HELPERS (internos)
-- ============================================================
local function mkElement(h)
h = h or 40
local el = New("Frame",{
Size=UDim2.new(1,0,0,h),
BackgroundColor3=T.Surface,
BorderSizePixel=0,
ZIndex=7,
},Page)
Corner(8,el)
Stroke(T.Border,0.6,el)
return el
end
local function mkTitle(parent, text, xOff, w)
return New("TextLabel",{
Size=UDim2.new(w or 0.55,-(xOff or 14),1,0),
Position=UDim2.new(0,xOff or 14,0,0),
BackgroundTransparency=1,
Text=text,TextColor3=T.Text,TextSize=11,
Font=Enum.Font.Gotham,TextXAlignment=Enum.TextXAlignment.Left,
ZIndex=8,
},parent)
end
local function hoverEl(el)
el.MouseEnter:Connect(function() tw(el,0.15,{BackgroundColor3=T.SurfaceHi}) end)
el.MouseLeave:Connect(function() tw(el,0.15,{BackgroundColor3=T.Surface}) end)
end
-- ============================================================
-- TAB OBJECT
-- ============================================================
local Tab = {}
-- ---- SECTION ----
function Tab:CreateSection(sname)
local sec = New("Frame",{
Size=UDim2.new(1,0,0,22),
BackgroundTransparency=1,ZIndex=7,
},Page)
New("TextLabel",{
Size=UDim2.new(1,-14,1,0),Position=UDim2.new(0,14,0,0),
BackgroundTransparency=1,Text=sname:upper(),
TextColor3=T.Accent,TextSize=9,Font=Enum.Font.GothamBold,
TextXAlignment=Enum.TextXAlignment.Left,ZIndex=8,
},sec)
-- line
New("Frame",{
Size=UDim2.new(1,-14,0,1),Position=UDim2.new(0,14,1,-1),
BackgroundColor3=T.AccentDim,BorderSizePixel=0,ZIndex=8,
},sec)
local sv = {}
function sv:Set(t) sec:FindFirstChildOfClass("TextLabel").Text = t:upper() end
return sv
end
-- ---- LABEL ----
function Tab:CreateLabel(text)
local el = New("Frame",{
Size=UDim2.new(1,0,0,32),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,ZIndex=7,
},Page)
Corner(8,el)
Stroke(T.Border,0.5,el)
local lbl = New("TextLabel",{
Size=UDim2.new(1,-28,1,0),Position=UDim2.new(0,14,0,0),
BackgroundTransparency=1,Text=text,TextColor3=T.TextDim,
TextSize=11,Font=Enum.Font.Gotham,TextXAlignment=Enum.TextXAlignment.Left,
ZIndex=8,TextWrapped=true,
},el)
local lv = {}
function lv:Set(t) lbl.Text=t end
return lv
end
-- ---- PARAGRAPH ----
function Tab:CreateParagraph(s)
local lines = math.max(1, math.ceil(#(s.Content or "") / 55))
local h = 36 + lines*14
local el = New("Frame",{
Size=UDim2.new(1,0,0,h),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,ZIndex=7,
},Page)
Corner(8,el)
Stroke(T.Border,0.5,el)
New("TextLabel",{
Size=UDim2.new(1,-28,0,16),Position=UDim2.new(0,14,0,8),
BackgroundTransparency=1,Text=s.Title or "",
TextColor3=T.Text,TextSize=11,Font=Enum.Font.GothamBold,
TextXAlignment=Enum.TextXAlignment.Left,ZIndex=8,
},el)
New("TextLabel",{
Size=UDim2.new(1,-28,1,-28),Position=UDim2.new(0,14,0,26),
BackgroundTransparency=1,Text=s.Content or "",
TextColor3=T.TextDim,TextSize=10,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Left,TextWrapped=true,ZIndex=8,
},el)
local pv = {}
function pv:Set(ns)
el:FindFirstChild("TextLabel").Text = ns.Title or ""
local all = el:GetChildren()
if all[2] then all[2].Text = ns.Content or "" end
end
return pv
end
-- ---- BUTTON ----
function Tab:CreateButton(s)
local el = mkElement(40)
hoverEl(el)
mkTitle(el, s.Name)
-- reveal highlight
local revealBtn = New("TextButton",{
Size=UDim2.new(0,90,0,26),
Position=UDim2.new(1,-100,0.5,-13),
BackgroundColor3=T.Accent,BorderSizePixel=0,
Text="Run",TextColor3=T.White,TextSize=10,Font=Enum.Font.GothamBold,
ZIndex=9,
},el)
Corner(7,revealBtn)
revealBtn.MouseEnter:Connect(function() tw(revealBtn,0.1,{BackgroundColor3=T.AccentGlow}) end)
revealBtn.MouseLeave:Connect(function() tw(revealBtn,0.1,{BackgroundColor3=T.Accent}) end)
revealBtn.MouseButton1Click:Connect(function()
tw(revealBtn,0.1,{BackgroundColor3=T.White})
task.spawn(function()
local ok,err=pcall(s.Callback)
if not ok then
tw(el,0.3,{BackgroundColor3=Color3.fromRGB(60,15,15)})
task.wait(0.6)
tw(el,0.3,{BackgroundColor3=T.Surface})
else
SaveConfig()
end
end)
task.wait(0.1)
tw(revealBtn,0.2,{BackgroundColor3=T.Accent})
end)
local bv = {}
function bv:Set(t) el:FindFirstChildOfClass("TextLabel").Text=t end
return bv
end
-- ---- TOGGLE ----
function Tab:CreateToggle(s)
local el = mkElement(40)
hoverEl(el)
mkTitle(el, s.Name)
local track = New("Frame",{
Size=UDim2.new(0,42,0,22),
Position=UDim2.new(1,-56,0.5,-11),
BackgroundColor3=s.CurrentValue and T.ToggleOn or T.ToggleOff,
BorderSizePixel=0,ZIndex=9,
},el)
Corner(11,track)
local thumb = New("Frame",{
Size=UDim2.new(0,16,0,16),
Position=s.CurrentValue and UDim2.new(1,-19,0.5,-8) or UDim2.new(0,3,0.5,-8),
BackgroundColor3=T.White,BorderSizePixel=0,ZIndex=10,
},track)
Corner(8,thumb)
local interact = New("TextButton",{
Size=UDim2.new(1,0,1,0),BackgroundTransparency=1,Text="",ZIndex=11,
},track)
interact.MouseButton1Click:Connect(function()
s.CurrentValue = not s.CurrentValue
if s.CurrentValue then
tw(track,0.25,{BackgroundColor3=T.ToggleOn})
tw(thumb,0.25,{Position=UDim2.new(1,-19,0.5,-8)})
else
tw(track,0.25,{BackgroundColor3=T.ToggleOff})
tw(thumb,0.25,{Position=UDim2.new(0,3,0.5,-8)})
end
task.spawn(function() pcall(s.Callback, s.CurrentValue) end)
SaveConfig()
end)
if s.Flag then NoirX.Flags[s.Flag] = s end
local tv = {}
tv.Type = "Toggle"
function tv:Set(val)
s.CurrentValue = val
if val then
tw(track,0.25,{BackgroundColor3=T.ToggleOn})
tw(thumb,0.25,{Position=UDim2.new(1,-19,0.5,-8)})
else
tw(track,0.25,{BackgroundColor3=T.ToggleOff})
tw(thumb,0.25,{Position=UDim2.new(0,3,0.5,-8)})
end
task.spawn(function() pcall(s.Callback, s.CurrentValue) end)
end
s.Set = tv.Set
return s
end
-- ---- SLIDER ----
function Tab:CreateSlider(s)
local el = mkElement(52)
hoverEl(el)
mkTitle(el, s.Name, 14, 0.5)
local valLbl = New("TextLabel",{
Size=UDim2.new(0,60,0,16),
Position=UDim2.new(1,-70,0,4),
BackgroundTransparency=1,
Text=tostring(s.CurrentValue)..(s.Suffix and (" "..s.Suffix) or ""),
TextColor3=T.Accent,TextSize=10,Font=Enum.Font.GothamBold,
TextXAlignment=Enum.TextXAlignment.Right,ZIndex=9,
},el)
local track = New("Frame",{
Size=UDim2.new(1,-28,0,6),
Position=UDim2.new(0,14,0,32),
BackgroundColor3=T.SliderBG,BorderSizePixel=0,ZIndex=9,
},el)
Corner(3,track)
local fill = New("Frame",{
Size=UDim2.new(
math.clamp((s.CurrentValue-s.Range[1])/(s.Range[2]-s.Range[1]),0,1),
0,1,0),
BackgroundColor3=T.SliderFill,BorderSizePixel=0,ZIndex=10,
},track)
Corner(3,fill)
local handle = New("Frame",{
Size=UDim2.new(0,14,0,14),
Position=UDim2.new(
math.clamp((s.CurrentValue-s.Range[1])/(s.Range[2]-s.Range[1]),0,1),
-7,0.5,-7),
BackgroundColor3=T.White,BorderSizePixel=0,ZIndex=11,
},track)
Corner(7,handle)
local dragging = false
local interact = New("TextButton",{
Size=UDim2.new(1,0,3,0),Position=UDim2.new(0,0,-1,0),
BackgroundTransparency=1,Text="",ZIndex=12,
},track)
local function updateSlider(mx)
local rel = math.clamp((mx - track.AbsolutePosition.X)/track.AbsoluteSize.X,0,1)
local raw = s.Range[1] + rel*(s.Range[2]-s.Range[1])
local val = math.floor(raw/s.Increment+0.5)*s.Increment
val = math.clamp(val, s.Range[1], s.Range[2])
s.CurrentValue = val
local pct = (val-s.Range[1])/(s.Range[2]-s.Range[1])
tw(fill,0.08,{Size=UDim2.new(pct,0,1,0)})
tw(handle,0.08,{Position=UDim2.new(pct,-7,0.5,-7)})
valLbl.Text = tostring(val)..(s.Suffix and (" "..s.Suffix) or "")
task.spawn(function() pcall(s.Callback, val) end)
SaveConfig()
end
interact.InputBegan:Connect(function(i)
if i.UserInputType==Enum.UserInputType.MouseButton1 then dragging=true end
end)
UIS.InputEnded:Connect(function(i)
if i.UserInputType==Enum.UserInputType.MouseButton1 then dragging=false end
end)
UIS.InputChanged:Connect(function(i)
if dragging and i.UserInputType==Enum.UserInputType.MouseMovement then
updateSlider(UIS:GetMouseLocation().X)
end
end)
interact.MouseButton1Down:Connect(function()
updateSlider(UIS:GetMouseLocation().X)
end)
if s.Flag then NoirX.Flags[s.Flag] = s end
function s:Set(val)
s.CurrentValue = math.clamp(val, s.Range[1], s.Range[2])
local pct=(s.CurrentValue-s.Range[1])/(s.Range[2]-s.Range[1])
tw(fill,0.2,{Size=UDim2.new(pct,0,1,0)})
tw(handle,0.2,{Position=UDim2.new(pct,-7,0.5,-7)})
valLbl.Text=tostring(s.CurrentValue)..(s.Suffix and (" "..s.Suffix) or "")
task.spawn(function() pcall(s.Callback, s.CurrentValue) end)
end
return s
end
-- ---- INPUT ----
function Tab:CreateInput(s)
local el = mkElement(40)
hoverEl(el)
mkTitle(el, s.Name)
local box = New("TextBox",{
Size=UDim2.new(0,140,0,26),
Position=UDim2.new(1,-150,0.5,-13),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,
Text="",PlaceholderText=s.PlaceholderText or "...",
PlaceholderColor3=T.TextDim,TextColor3=T.Text,
TextSize=11,Font=Enum.Font.Gotham,
ClearTextOnFocus=false,ZIndex=9,
},el)
Corner(7,box)
Stroke(T.Border,0.6,box)
Pad(8,8,0,0,box)
box.FocusLost:Connect(function()
task.spawn(function() pcall(s.Callback, box.Text) end)
if s.RemoveTextAfterFocusLost then box.Text="" end
SaveConfig()
end)
local iv = {}
function iv:Set(t) box.Text=t end
return iv
end
-- ---- DROPDOWN ----
function Tab:CreateDropdown(s)
if typeof(s.CurrentOption)=="string" then s.CurrentOption={s.CurrentOption} end
if not s.MultipleOptions then s.CurrentOption={s.CurrentOption[1]} end
local function displayText()
if #s.CurrentOption==0 then return "None"
elseif #s.CurrentOption==1 then return s.CurrentOption[1]
else return "Various ("..#s.CurrentOption..")" end
end
local el = New("Frame",{
Size=UDim2.new(1,0,0,40),
BackgroundColor3=T.Surface,BorderSizePixel=0,ZIndex=7,
ClipsDescendants=false,
},Page)
Corner(8,el)
Stroke(T.Border,0.6,el)
hoverEl(el)
mkTitle(el, s.Name)
local selLbl = New("TextLabel",{
Size=UDim2.new(0,120,1,0),Position=UDim2.new(1,-160,0,0),
BackgroundTransparency=1,Text=displayText(),
TextColor3=T.TextDim,TextSize=10,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Right,ZIndex=8,
},el)
local arrow = New("TextLabel",{
Size=UDim2.new(0,20,1,0),Position=UDim2.new(1,-26,0,0),
BackgroundTransparency=1,Text="▾",
TextColor3=T.TextDim,TextSize=11,ZIndex=8,
Font=Enum.Font.GothamBold,
},el)
-- dropdown panel (parented to Root so it overlaps everything)
local panel = New("Frame",{
Size=UDim2.new(0,el.AbsoluteSize.X,0,0),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,
Visible=false,ZIndex=50,ClipsDescendants=true,
},Root)
Corner(8,panel)
Stroke(T.BorderHi,0.7,panel)
local panelList = New("ScrollingFrame",{
Size=UDim2.new(1,-4,1,0),Position=UDim2.new(0,2,0,0),
BackgroundTransparency=1,BorderSizePixel=0,
ScrollBarThickness=2,ScrollBarImageColor3=T.TextDim,
CanvasSize=UDim2.new(0,0,0,0),AutomaticCanvasSize=Enum.AutomaticSize.Y,
ZIndex=51,
},panel)
ListLayout(panelList,2)
Pad(4,4,4,4,panelList)
local function refreshPanel()
for _, c in ipairs(panelList:GetChildren()) do
if c:IsA("TextButton") then c:Destroy() end
end
for _, opt in ipairs(s.Options) do
local isSelected = table.find(s.CurrentOption, opt) ~= nil
local ob = New("TextButton",{
Size=UDim2.new(1,0,0,28),
BackgroundColor3=isSelected and T.AccentDim or T.Surface,
BackgroundTransparency=isSelected and 0 or 0.4,
BorderSizePixel=0,
Text=" "..opt,TextColor3=isSelected and T.White or T.Text,
TextSize=11,Font=Enum.Font.Gotham,
TextXAlignment=Enum.TextXAlignment.Left,
ZIndex=52,
},panelList)
Corner(6,ob)
ob.MouseEnter:Connect(function()
if not table.find(s.CurrentOption,opt) then
tw(ob,0.1,{BackgroundTransparency=0,BackgroundColor3=T.SurfaceHi})
end
end)
ob.MouseLeave:Connect(function()
if not table.find(s.CurrentOption,opt) then
tw(ob,0.1,{BackgroundTransparency=0.4,BackgroundColor3=T.Surface})
end
end)
ob.MouseButton1Click:Connect(function()
if not s.MultipleOptions then
s.CurrentOption = {opt}
else
local idx = table.find(s.CurrentOption,opt)
if idx then table.remove(s.CurrentOption,idx)
else table.insert(s.CurrentOption,opt) end
end
selLbl.Text = displayText()
refreshPanel()
task.spawn(function() pcall(s.Callback, s.CurrentOption) end)
if not s.MultipleOptions then
tw(panel,0.15,{Size=UDim2.new(0,el.AbsoluteSize.X,0,0)})
task.wait(0.18); panel.Visible=false
end
SaveConfig()
end)
end
end
refreshPanel()
local opened = false
local interact = New("TextButton",{
Size=UDim2.new(1,0,1,0),BackgroundTransparency=1,Text="",ZIndex=9,
},el)
local function positionPanel()
local abs = el.AbsolutePosition
local sz = el.AbsoluteSize
local optH= math.min(#s.Options*30+12, 200)
local screenH = workspace.CurrentCamera.ViewportSize.Y
local yPos = abs.Y+sz.Y+4
if yPos+optH > screenH then yPos = abs.Y-optH-4 end
panel.Position = UDim2.new(0, abs.X, 0, yPos)
panel.Size = UDim2.new(0, sz.X, 0, 0)
return optH
end
interact.MouseButton1Click:Connect(function()
if opened then
opened=false
tw(panel,0.15,{Size=UDim2.new(0,el.AbsoluteSize.X,0,0)})
tw(arrow,0.15,{Rotation=0})
task.wait(0.18); panel.Visible=false
else
opened=true
local optH = positionPanel()
panel.Visible=true
tw(panel,0.2,{Size=UDim2.new(0,el.AbsoluteSize.X,0,optH)})
tw(arrow,0.15,{Rotation=180})
end
end)
if s.Flag then NoirX.Flags[s.Flag] = s end
function s:Set(opt)
if typeof(opt)=="string" then opt={opt} end
s.CurrentOption=opt
selLbl.Text=displayText()
refreshPanel()
task.spawn(function() pcall(s.Callback, s.CurrentOption) end)
end
return s
end
-- ---- KEYBIND ----
function Tab:CreateKeybind(s)
local el = mkElement(40)
hoverEl(el)
mkTitle(el, s.Name)
local kbox = New("TextButton",{
Size=UDim2.new(0,80,0,26),
Position=UDim2.new(1,-90,0.5,-13),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,
Text=s.CurrentKeybind or "None",
TextColor3=T.Accent,TextSize=10,Font=Enum.Font.GothamBold,
ZIndex=9,
},el)
Corner(7,kbox)
Stroke(T.Border,0.6,kbox)
local listening = false
kbox.MouseButton1Click:Connect(function()
listening=true
kbox.Text="..."
kbox.TextColor3=T.Warning
end)
UIS.InputBegan:Connect(function(input, processed)
if listening then
if input.KeyCode ~= Enum.KeyCode.Unknown then
local split = tostring(input.KeyCode):split(".")
local key = split[3]
s.CurrentKeybind = key
kbox.Text = key
kbox.TextColor3 = T.Accent
listening = false
SaveConfig()
end
elseif not processed and s.CurrentKeybind then
if UIS:GetFocusedTextBox() then return end
pcall(function()
if input.KeyCode == Enum.KeyCode[s.CurrentKeybind] then
task.spawn(function() pcall(s.Callback) end)
end
end)
end
end)
if s.Flag then NoirX.Flags[s.Flag] = s end
function s:Set(key)
s.CurrentKeybind=tostring(key)
kbox.Text=tostring(key)
end
return s
end
-- ---- COLOR PICKER (simplificado, funcional) ----
function Tab:CreateColorPicker(s)
s.Type = "ColorPicker"
s.Color = s.Color or Color3.fromRGB(255,255,255)
local h,sat,v = s.Color:ToHSV()
local el = mkElement(40)
hoverEl(el)
mkTitle(el, s.Name)
local preview = New("Frame",{
Size=UDim2.new(0,28,0,20),
Position=UDim2.new(1,-42,0.5,-10),
BackgroundColor3=s.Color,BorderSizePixel=0,ZIndex=9,
},el)
Corner(6,preview)
Stroke(T.Border,0.6,preview)
-- expanded picker
local picker = New("Frame",{
Size=UDim2.new(1,0,0,0),
BackgroundColor3=T.BGDeep,BorderSizePixel=0,
ClipsDescendants=true,ZIndex=8,
},Page)
Corner(8,picker)
Stroke(T.Border,0.5,picker)
local pickerVisible = false
-- hue slider
local hueGrad = New("Frame",{
Size=UDim2.new(1,-28,0,16),Position=UDim2.new(0,14,0,12),
BorderSizePixel=0,ZIndex=9,
},picker)
Corner(4,hueGrad)
local uiGrad = New("UIGradient",{},hueGrad)
uiGrad.Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.fromHSV(0,1,1)),
ColorSequenceKeypoint.new(0.17, Color3.fromHSV(0.17,1,1)),
ColorSequenceKeypoint.new(0.33, Color3.fromHSV(0.33,1,1)),
ColorSequenceKeypoint.new(0.5, Color3.fromHSV(0.5,1,1)),
ColorSequenceKeypoint.new(0.67, Color3.fromHSV(0.67,1,1)),
ColorSequenceKeypoint.new(0.83, Color3.fromHSV(0.83,1,1)),
ColorSequenceKeypoint.new(1, Color3.fromHSV(1,1,1)),
})
local hueHandle = New("Frame",{
Size=UDim2.new(0,8,1,4),Position=UDim2.new(h,-4,-0.1,0),
BackgroundColor3=T.White,BorderSizePixel=0,ZIndex=10,
},hueGrad)
Corner(3,hueHandle)
local hexBox = New("TextBox",{
Size=UDim2.new(1,-28,0,24),Position=UDim2.new(0,14,0,34),
BackgroundColor3=T.Surface,BorderSizePixel=0,
Text=string.format("#%02X%02X%02X",s.Color.R*255,s.Color.G*255,s.Color.B*255),
TextColor3=T.Text,TextSize=10,Font=Enum.Font.GothamBold,
ClearTextOnFocus=false,ZIndex=9,
},picker)
Corner(6,hexBox)
Pad(8,8,0,0,hexBox)
Stroke(T.Border,0.5,hexBox)
local function applyColor()
s.Color = Color3.fromHSV(h,sat,v)
preview.BackgroundColor3 = s.Color
hexBox.Text = string.format("#%02X%02X%02X",s.Color.R*255,s.Color.G*255,s.Color.B*255)
task.spawn(function() pcall(s.Callback, s.Color) end)
SaveConfig()
end
-- hue drag
local hueDrag = false
local hInt = New("TextButton",{
Size=UDim2.new(1,0,1,0),BackgroundTransparency=1,Text="",ZIndex=11,
},hueGrad)
hInt.InputBegan:Connect(function(i)
if i.UserInputType==Enum.UserInputType.MouseButton1 then hueDrag=true end
end)
UIS.InputEnded:Connect(function(i)
if i.UserInputType==Enum.UserInputType.MouseButton1 then hueDrag=false end
end)
UIS.InputChanged:Connect(function(i)
if hueDrag and i.UserInputType==Enum.UserInputType.MouseMovement then
h = math.clamp((UIS:GetMouseLocation().X-hueGrad.AbsolutePosition.X)/hueGrad.AbsoluteSize.X,0,1)
hueHandle.Position = UDim2.new(h,-4,-0.1,0)
applyColor()
end
end)
hInt.MouseButton1Down:Connect(function()
h=math.clamp((UIS:GetMouseLocation().X-hueGrad.AbsolutePosition.X)/hueGrad.AbsoluteSize.X,0,1)
hueHandle.Position=UDim2.new(h,-4,-0.1,0)
applyColor()
end)
hexBox.FocusLost:Connect(function()
pcall(function()
local r,g,b=hexBox.Text:match("^#?(%x%x)(%x%x)(%x%x)$")
s.Color=Color3.fromRGB(tonumber(r,16),tonumber(g,16),tonumber(b,16))
h,sat,v=s.Color:ToHSV()
preview.BackgroundColor3=s.Color
task.spawn(function() pcall(s.Callback,s.Color) end)
SaveConfig()
end)
end)
-- toggle expand
local interact = New("TextButton",{
Size=UDim2.new(1,0,1,0),BackgroundTransparency=1,Text="",ZIndex=10,
},el)
interact.MouseButton1Click:Connect(function()
pickerVisible = not pickerVisible
if pickerVisible then
picker.Visible=true
tw(picker,0.2,{Size=UDim2.new(1,0,0,70)})
else
tw(picker,0.15,{Size=UDim2.new(1,0,0,0)})
task.wait(0.18); picker.Visible=false
end
end)
if s.Flag then NoirX.Flags[s.Flag] = s end
function s:Set(color)
s.Color=color; h,sat,v=color:ToHSV()
preview.BackgroundColor3=color
hexBox.Text=string.format("#%02X%02X%02X",color.R*255,color.G*255,color.B*255)
task.spawn(function() pcall(s.Callback,color) end)
end
return s
end
return Tab
end -- CreateTab
-- ---- loading animation ----
task.spawn(function()
-- simple fade in
Main.BackgroundTransparency = 1
ContentArea.Visible = false
task.wait(0.05)
tw(Main, 0.4, {BackgroundTransparency=0})
task.wait(0.35)
ContentArea.Visible = true
-- load config after 3.5s like Rayfield
task.wait(3.5)
LoadConfig()
end)
return Window
--[[
NoirX Tz — UI Library
Fluent Dark | Sidebar Layout
by Tz (base: Rayfield open source)
]]
-- ============================================================
-- SERVICES
-- ============================================================
local UIS = game:GetService("UserInputService")
local TweenSvc = game:GetService("TweenService")
local HttpSvc = game:GetService("HttpService")
local RunSvc = game:GetService("RunService")
local Players = game:GetService("Players")
local CoreGui = game:GetService("CoreGui")
local LocalPlayer = Players.LocalPlayer
-- ============================================================
-- CONFIG & SAVE
-- ============================================================
local FOLDER = "NoirX"
local CFG_FOLDER = FOLDER .. "/Configurations"
local CFG_EXT = ".nxcfg"
local function safeMakeFolder(path)
pcall(function()
if not isfolder(path) then makefolder(path) end
end)
end
safeMakeFolder(FOLDER)
safeMakeFolder(CFG_FOLDER)
-- ============================================================
-- THEME (Fluent Dark / Noir)
-- ============================================================
local T = {
-- base
BG = Color3.fromRGB(18, 18, 22 ), -- ventana
BGDeep = Color3.fromRGB(12, 12, 15 ), -- sidebar
Surface = Color3.fromRGB(28, 28, 34 ), -- elementos
SurfaceHi = Color3.fromRGB(36, 36, 44 ), -- hover
-- accent
Accent = Color3.fromRGB(0, 120, 212), -- azul fluent
AccentDim = Color3.fromRGB(0, 80, 150),
AccentGlow = Color3.fromRGB(30, 140, 240),
-- texto
Text = Color3.fromRGB(230, 230, 235),
TextDim = Color3.fromRGB(130, 130, 145),
TextDisabled= Color3.fromRGB(70, 70, 80 ),
-- bordes
Border = Color3.fromRGB(45, 45, 55 ),
BorderHi = Color3.fromRGB(65, 65, 80 ),
-- estados
Success = Color3.fromRGB(20, 200, 100),
Error = Color3.fromRGB(200, 50, 50 ),
Warning = Color3.fromRGB(220, 170, 30 ),
-- toggle
ToggleBG = Color3.fromRGB(25, 25, 32 ),
ToggleOn = Color3.fromRGB(0, 120, 212),
ToggleOff = Color3.fromRGB(80, 80, 95 ),
-- slider
SliderBG = Color3.fromRGB(30, 30, 38 ),
SliderFill = Color3.fromRGB(0, 120, 212),
-- sidebar
SidebarW = 160,
-- misc
White = Color3.fromRGB(255, 255, 255),
Black = Color3.fromRGB(0, 0, 0 ),
}
-- ============================================================
-- TWEEN HELPERS
-- ============================================================
local function tw(obj, t, props)
TweenSvc:Create(obj, TweenInfo.new(t, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), props):Play()
end
local function twIn(obj, t, props)
TweenSvc:Create(obj, TweenInfo.new(t, Enum.EasingStyle.Quint, Enum.EasingDirection.In), props):Play()
end
-- ============================================================
-- INSTANCE HELPERS
-- ============================================================
local function New(cls, props, parent)
local o = Instance.new(cls)
for k, v in pairs(props or {}) do o[k] = v end
if parent then o.Parent = parent end
return o
end
local function Corner(r, p) return New("UICorner",{CornerRadius=UDim.new(0,r)},p) end
local function Stroke(c,th,p) local s=New("UIStroke",{Color=c,Thickness=th or 0.8},p); return s end
local function Pad(l,r,t,b,p) return New("UIPadding",{PaddingLeft=UDim.new(0,l),PaddingRight=UDim.new(0,r),PaddingTop=UDim.new(0,t),PaddingBottom=UDim.new(0,b)},p) end
local function ListLayout(p,sp,dir)
return New("UIListLayout",{SortOrder=Enum.SortOrder.LayoutOrder,Padding=UDim.new(0,sp or 6),FillDirection=dir or Enum.FillDirection.Vertical},p)
end
-- ============================================================
-- LIBRARY TABLE
-- ============================================================
local NoirX = { Flags = {} }
-- ============================================================
-- ROOT GUI
-- ============================================================
for _, v in ipairs(CoreGui:GetChildren()) do
if v.Name == "NoirX_Tz" then v:Destroy() end
end
local Root = New("ScreenGui", {
Name = "NoirX_Tz",
ResetOnSpawn = false,
ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
IgnoreGuiInset = true,
}, CoreGui)
-- Notifications container
local NotifContainer = New("Frame", {
Size = UDim2.new(0, 310, 1, 0),
Position = UDim2.new(1, -320, 0, 0),
BackgroundTransparency = 1,
ZIndex = 200,
}, Root)
ListLayout(NotifContainer, 8)
Pad(0,0,12,12,NotifContainer)
-- ============================================================
-- NOTIFY
-- ============================================================
function NoirX:Notify(cfg)
task.spawn(function()
local dur = cfg.Duration or 5
local notif = New("Frame", {
Size = UDim2.new(1, 0, 0, 0),
BackgroundColor3 = T.Surface,
BackgroundTransparency = 1,
ClipsDescendants = true,
ZIndex = 200,
}, NotifContainer)
Corner(10, notif)
Stroke(T.BorderHi, 0.7, notif)
end
-- ============================================================
-- SAVE / LOAD HELPERS
-- ============================================================
local CFileName = nil
local CEnabled = false
local function SaveConfig()
if not CEnabled then return end
local data = {}
for k, v in pairs(NoirX.Flags) do
if v.Type == "ColorPicker" then
data[k] = {R = v.Color.R255, G = v.Color.G255, B = v.Color.B*255}
else
data[k] = v.CurrentValue or v.CurrentKeybind or v.CurrentOption or v.Color
end
end
pcall(writefile, CFG_FOLDER.."/"..CFileName..CFG_EXT, HttpSvc:JSONEncode(data))
end
local function LoadConfig()
if not CEnabled then return end
pcall(function()
local path = CFG_FOLDER.."/"..CFileName..CFG_EXT
if not isfile(path) then return end
local data = HttpSvc:JSONDecode(readfile(path))
for k, v in pairs(data) do
if NoirX.Flags[k] then
task.spawn(function()
local f = NoirX.Flags[k]
if f.Type == "ColorPicker" then
f:Set(Color3.fromRGB(v.R, v.G, v.B))
else
if f.CurrentValue ~= v or f.CurrentKeybind ~= v or f.CurrentOption ~= v then
f:Set(v)
end
end
end)
end
end
NoirX:Notify({Title = "Config Loaded", Content = "Settings restored from last session.", Duration = 4})
end)
end
-- ============================================================
-- CREATE WINDOW
-- ============================================================
function NoirX:CreateWindow(cfg)
cfg = cfg or {}
local WIN_W = 640
local WIN_H = 460
local SIDE_W = T.SidebarW
end -- CreateWindow
-- ============================================================
-- DESTROY
-- ============================================================
function NoirX:Destroy()
Root:Destroy()
end
return NoirX