--//========================================================================//-- --// ENVIRONMENT SETUP //-- --//========================================================================//-- -- Clean up any previous instances to prevent memory leaks and conflicts if getgenv().Gui2Lua then pcall(getgenv().Gui2Lua.Cleanup) end -- Roblox Services local UserInputService = game:GetService("UserInputService") local MarketplaceService = game:GetService("MarketplaceService") local Players = game:GetService("Players") local CoreGui = game:GetService("CoreGui") local RunService = game:GetService("RunService") -- Executor Capability Checks local hasFileSystemAccess = typeof(writefile) == 'function' and typeof(makefolder) == 'function' local hasDecompiler = typeof(decompile) == 'function' local getAbsPath = typeof(getcurrentexecutorpath) == 'function' and getcurrentexecutorpath or function() return "workspace\\" end --//========================================================================//-- --// CONFIGURATION & STATE //-- --//========================================================================//-- local config = { convertLocalScripts = true } --//========================================================================//-- --// UTILITIES //-- --//========================================================================//-- local function GetGameName() local success, result = pcall(function() return MarketplaceService:GetProductInfo(game.PlaceId) end) local name = (success and result and result.Name) return name and name:gsub("[\"/\\?%*:|<>%c]", "") or "UntitledGame" end local function ResolvePath(path) if not path or path == "" then return nil end local current = game for _, partName in ipairs(path:split('.')) do local newCurrent = current:FindFirstChild(partName) if not newCurrent then if current == Players and partName == "LocalPlayer" then newCurrent = Players.LocalPlayer else return nil end end current = newCurrent end return current end local function SanitizeForFilename(name) local sanitized = name:gsub('[^%w%s%-_]', '') if sanitized:match('^[%z\t ]*$') then return "UntitledGUI" end -- Basic latin character replacements for broader filesystem compatibility sanitized = sanitized:gsub('[áàâäãåæ]','a'):gsub('[çćč]','c') :gsub('[éèêë]','e'):gsub('[íìîï]','i'):gsub('[ñ]','n') :gsub('[óòôöõø]','o'):gsub('[úùûü]','u'):gsub('[ýÿ]','y') return sanitized end --//========================================================================//-- --// COMPREHENSIVE FIDELITY SERIALIZER //-- --//========================================================================//-- local Serializer = {} do -- Properties to ignore across all instances for safety and efficiency local IGNORED_PROPS = {"Archivable", "ClassName", "Parent", "Children", "RobloxLocked", "AbsolutePosition", "AbsoluteRotation", "AbsoluteSize", "Source", "Adornee"} -- Adornee is set to nil to keep scripts self-contained -- Type-specific formatters for generating valid Lua code local FORMATTERS = { string = function(v) return string.format("%q", v) end, Content = function(v) return string.format("%q", v) end, Color3 = function(v) return string.format("Color3.fromRGB(%d,%d,%d)", math.floor(v.R*255.5), math.floor(v.G*255.5), math.floor(v.B*255.5)) end, Vector2 = function(v) return string.format("Vector2.new(%.7g,%.7g)", v.X, v.Y) end, Vector3 = function(v) return string.format("Vector3.new(%.7g,%.7g,%.7g)", v.X, v.Y, v.Z) end, UDim2 = function(v) return string.format("UDim2.new(%.7g,%d,%.7g,%d)", v.X.Scale, v.X.Offset, v.Y.Scale, v.Y.Offset) end, Rect = function(v) return string.format("Rect.new(%.7g,%.7g,%.7g,%.7g)", v.Min.X, v.Min.Y, v.Max.X, v.Max.Y) end, EnumItem = function(v) return string.format("Enum.%s.%s", v.EnumType.Name, v.Name) end, NumberSequence = function(v) local p={}; for _,k in ipairs(v.Keypoints) do table.insert(p,string.format("NumberSequenceKeypoint.new(%.7g,%.7g,%.7g)",k.Time,k.Value,k.Envelope)) end; return string.format("NumberSequence.new({%s})",table.concat(p,",")) end, ColorSequence = function(v) local p={}; for _,k in ipairs(v.Keypoints) do local c=k.Value table.insert(p,string.format("ColorSequenceKeypoint.new(%.7g,Color3.fromRGB(%d,%d,%d))", k.Time,math.floor(c.R*255.5),math.floor(c.G*255.5),math.floor(c.B*255.5))) end; return string.format("ColorSequence.new({%s})",table.concat(p,",")) end, Instance = function() return "nil --[[Instance Reference]]--" end } local function FormatValue(v) return (FORMATTERS[typeof(v)] and FORMATTERS[typeof(v)](v)) or tostring(v) end function Serializer:Convert(target, path) local output, varMap, usedNames = {}, {}, {} local function getVarName(inst) if varMap[inst] then return varMap[inst] end local base = inst.Name:match("^[%a_][%w_]*$") and inst.Name or inst.ClassName local name, i = base, 1 while usedNames[name] do i+=1; name=base.."_"..tostring(i) end usedNames[name]=true; varMap[inst]=name return name end local function genCode(inst, indent) -- Ignore server-side scripts completely if inst:IsA("Script") or inst:IsA("ModuleScript") then return "" end local var, ind = getVarName(inst), string.rep(" ", indent) local code = {string.format("%slocal %s=Instance.new(\"%s\")", ind, var, inst.ClassName)} local props, temp = {}, Instance.new(inst.ClassName) table.insert(props, string.format('%s%s.Name=%q', ind, var, inst.Name)) pcall(function() for p,_ in pairs(inst:GetProperties()) do if not table.find(IGNORED_PROPS,p) and not table.find(debug.getinfo(inst[p]).what,"C") and inst[p]~=temp[p] then table.insert(props, string.format("%s%s.%s=%s",ind,var,p,FormatValue(inst[p]))) end end end) temp:Destroy(); table.insert(code, table.concat(props,"\n")) if config.convertLocalScripts and inst:IsA("LocalScript") then local ok, src = pcall(hasDecompiler and decompile, inst) if not ok or not src or src=="" then src=inst.Source; table.insert(code,ind.."--// WARN: Decompilation failed, using raw .Source") else table.insert(code,ind.."--// Source decompiled by executor.") end if src and src~="" then table.insert(code,string.format("%s%s.Source=[[\n%s\n]]",ind,var,src)) end end local children=inst:GetChildren() if #children>0 then for _,c in ipairs(children) do table.insert(code, genCode(c,indent)) end table.insert(code, "") -- Add a newline for parenting for _,c in ipairs(children) do if not (c:IsA("Script") or c:IsA("ModuleScript")) then table.insert(code,string.format("%s%s.Parent=%s",ind,getVarName(c),var)) end end end return table.concat(code,"\n") end table.insert(output,"--// Tool: Gui2Lua by FE Scripter"); table.insert(output,string.format("--// Path: game.%s",path)); table.insert(output,string.format("--// Game: %s",GetGameName())); table.insert(output,string.format("--// Time: %s",os.date("!%Y-%m-%dT%H:%M:%SZ"))) table.insert(output,"\nreturn function()"); table.insert(output,genCode(target,1)); table.insert(output,string.format("\n return %s",getVarName(target))); table.insert(output,"end") return table.concat(output,"\n") end end --//========================================================================//-- --// MODERN GUI CONSTRUCTION //-- --//========================================================================//-- local Gui2Lua=Instance.new("ScreenGui"); Gui2Lua.Name="Gui2Lua"; Gui2Lua.ZIndexBehavior=Enum.ZIndexBehavior.Global; Gui2Lua.ResetOnSpawn=false local Main=Instance.new("Frame"); Main.Name="Main"; Main.Parent=Gui2Lua; Main.AnchorPoint=Vector2.new(0.5,0.5); Main.Position=UDim2.fromScale(0.5,0.5); Main.Size=UDim2.fromOffset(300,380); Main.BackgroundColor3=Color3.fromRGB(28,29,34); Main.BorderSizePixel=0 local Corner=Instance.new("UICorner",Main); Corner.CornerRadius=UDim.new(0,12) local Stroke=Instance.new("UIStroke",Main); Stroke.ApplyStrokeMode=Enum.ApplyStrokeMode.Border; Stroke.Color=Color3.fromRGB(60,62,70); Stroke.Thickness=1.5 local AnimatedGradient=Instance.new("UIGradient",Main); AnimatedGradient.Rotation=45; AnimatedGradient.Color=ColorSequence.new({ColorSequenceKeypoint.new(0,Color3.fromRGB(43,45,51)),ColorSequenceKeypoint.new(0.5,Color3.fromRGB(28,29,34)),ColorSequenceKeypoint.new(1,Color3.fromRGB(43,45,51))}) local TitleBar=Instance.new("Frame"); TitleBar.Name="TitleBar"; TitleBar.Parent=Main; TitleBar.BackgroundTransparency=1; TitleBar.Size=UDim2.new(1,0,0,50); local Title=Instance.new("TextLabel"); Title.Name="Title"; Title.Parent=TitleBar; Title.BackgroundTransparency=1; Title.Size=UDim2.new(1,-60,1,0); Title.Position=UDim2.fromOffset(15,0); Title.Font=Enum.Font.GothamBold; Title.Text="Gui To Lua"; Title.TextColor3=Color3.fromRGB(240,240,245); Title.TextSize=22; Title.TextXAlignment=Enum.TextXAlignment.Left local CloseBtn=Instance.new("ImageButton"); CloseBtn.Name="CloseButton"; CloseBtn.Parent=TitleBar; CloseBtn.BackgroundTransparency=1; CloseBtn.AnchorPoint=Vector2.new(1,0.5); CloseBtn.Position=UDim2.new(1,-15,0.5,0); CloseBtn.Size=UDim2.fromOffset(24,24); CloseBtn.Image="rbxassetid://5994821894"; CloseBtn.ImageColor3=Color3.fromRGB(180,180,190) local Content=Instance.new("Frame"); Content.Name="Content"; Content.Parent=Main; Content.BackgroundTransparency=1; Content.Position=UDim2.new(0.5,0,0,50); Content.Size=UDim2.new(1,-30,1,-65); Content.AnchorPoint=Vector2.new(0.5,0) local ListLayout=Instance.new("UIListLayout",Content); ListLayout.FillDirection=Enum.FillDirection.Vertical; ListLayout.SortOrder=Enum.SortOrder.LayoutOrder; ListLayout.Padding=UDim.new(0,15) local PathInput=Instance.new("TextBox"); PathInput.Name="PathInput"; PathInput.Parent=Content; PathInput.BackgroundColor3=Color3.fromRGB(22,23,26); PathInput.Size=UDim2.new(1,0,0,50); PathInput.Font=Enum.Font.Code; PathInput.PlaceholderText="game.CoreGui..."; PathInput.TextColor3=Color3.fromRGB(200,200,210); PathInput.TextSize=16; PathInput.ClearTextOnFocus=false; PathInput.LayoutOrder=1 local InputCorner=Instance.new("UICorner",PathInput); InputCorner.CornerRadius=UDim.new(0,8) local InputStroke=Instance.new("UIStroke",PathInput); InputStroke.Color=Color3.fromRGB(60,62,70) local InputPadding=Instance.new("UIPadding",PathInput); InputPadding.PaddingLeft=UDim.new(0,15); InputPadding.PaddingRight=UDim.new(0,15) local ToggleFrame=Instance.new("Frame"); ToggleFrame.Name="ToggleFrame"; ToggleFrame.Parent=Content; ToggleFrame.BackgroundTransparency=1; ToggleFrame.Size=UDim2.new(1,0,0,50); ToggleFrame.LayoutOrder=2 local ToggleLabel=Instance.new("TextLabel",ToggleFrame); ToggleLabel.BackgroundTransparency=1; ToggleLabel.Size=UDim2.new(0.7,0,1,0); ToggleLabel.Font=Enum.Font.Gotham; ToggleLabel.Text="Convert LocalScripts"; ToggleLabel.TextSize=18; ToggleLabel.TextColor3=Color3.fromRGB(200,200,210); ToggleLabel.TextXAlignment=Enum.TextXAlignment.Left local ToggleButton=Instance.new("TextButton",ToggleFrame); ToggleButton.Name="ToggleButton"; ToggleButton.AnchorPoint=Vector2.new(1,0.5); ToggleButton.Position=UDim2.fromScale(1,0.5); ToggleButton.Size=UDim2.fromOffset(60,32); ToggleButton.BackgroundColor3=config.convertLocalScripts and Color3.fromRGB(0,180,130) or Color3.fromRGB(80,85,100); ToggleButton.Text="" local TBCorner=Instance.new("UICorner",ToggleButton); TBCorner.CornerRadius=UDim.new(1,0) local TBKnob=Instance.new("Frame",ToggleButton); TBKnob.Name="Knob"; TBKnob.AnchorPoint=Vector2.new(0.5,0.5); TBKnob.Position=config.convertLocalScripts and UDim2.fromScale(0.75,0.5) or UDim2.fromScale(0.25,0.5); TBKnob.Size=UDim2.fromOffset(24,24); TBKnob.BackgroundColor3=Color3.fromRGB(240,240,245); TBKnob.BorderSizePixel=0 local TBKCorner=Instance.new("UICorner",TBKnob); TBKCorner.CornerRadius=UDim.new(1,0) local ConvertBtn=Instance.new("TextButton"); ConvertBtn.Name="ConvertButton"; ConvertBtn.Parent=Content; ConvertBtn.BackgroundColor3=Color3.fromRGB(0,162,255); ConvertBtn.Size=UDim2.new(1,0,0,55); ConvertBtn.Font=Enum.Font.GothamBold; ConvertBtn.Text="CONVERT & SAVE"; ConvertBtn.TextColor3=Color3.fromRGB(255,255,255); ConvertBtn.TextSize=20; ConvertBtn.LayoutOrder=3 local BtnCorner=Instance.new("UICorner",ConvertBtn); BtnCorner.CornerRadius=UDim.new(0,8) local StatusLabel=Instance.new("TextLabel"); StatusLabel.Name="StatusLabel"; StatusLabel.Parent=Content; StatusLabel.BackgroundTransparency=1; StatusLabel.Size=UDim2.new(1,0,0,40); StatusLabel.Font=Enum.Font.Gotham; StatusLabel.Text=""; StatusLabel.TextColor3=Color3.fromRGB(150,150,160); StatusLabel.TextSize=14; StatusLabel.TextWrapped=true; StatusLabel.TextYAlignment=Enum.TextYAlignment.Top; StatusLabel.LayoutOrder=4 --//========================================================================//-- --// GUI LOGIC //-- --//========================================================================//-- local connections={} local function SetStatus(message,color) StatusLabel.Text=message; StatusLabel.TextColor3=color task.delay(8, function() if StatusLabel.Text==message then StatusLabel.Text="" end end) end -- Animated Gradient Loop local gradientAnim; gradientAnim=RunService.Heartbeat:Connect(function() local t=tick()*0.2 AnimatedGradient.Offset=Vector2.new(math.sin(t)*0.5, math.cos(t)*0.5) end) table.insert(connections, gradientAnim) -- Drag Logic table.insert(connections,TitleBar.InputBegan:Connect(function(inp) if inp.UserInputType==Enum.UserInputType.MouseButton1 or inp.UserInputType==Enum.UserInputType.Touch then local s,p=inp.Position,Main.Position; local c; c=UserInputService.InputChanged:Connect(function(i) if i.UserInputType==Enum.UserInputType.MouseMovement or i.UserInputType==Enum.UserInputType.Touch then Main.Position=UDim2.new(p.X.Scale,p.X.Offset+(i.Position-s).X,p.Y.Scale,p.Y.Offset+(i.Position-s).Y) end end); inp.Changed:Connect(function() if inp.UserInputState==Enum.UserInputState.End then c:Disconnect() end end) end end)) -- Close Button table.insert(connections,CloseBtn.MouseButton1Click:Connect(function() getgenv().Gui2Lua.Cleanup() end)) -- Toggle Button Logic table.insert(connections,ToggleButton.MouseButton1Click:Connect(function() config.convertLocalScripts = not config.convertLocalScripts local properties = {BackgroundColor3 = config.convertLocalScripts and Color3.fromRGB(0,180,130) or Color3.fromRGB(80,85,100)} local knobProperties = {Position = config.convertLocalScripts and UDim2.fromScale(0.75,0.5) or UDim2.fromScale(0.25,0.5)} game:GetService("TweenService"):Create(ToggleButton, TweenInfo.new(0.2), properties):Play() game:GetService("TweenService"):Create(TBKnob, TweenInfo.new(0.2, Enum.EasingStyle.Back), knobProperties):Play() end)) -- Main Conversion Button table.insert(connections,ConvertBtn.MouseButton1Click:Connect(function() if not hasFileSystemAccess then return SetStatus("Error: File system access unavailable.",Color3.fromRGB(255,80,80)) end local path=PathInput.Text; if not path or path:gsub("%s","")=="" then return SetStatus("Please enter a valid instance path.",Color3.fromRGB(255,200,80)) end local target=ResolvePath(path); if not target or not target:IsA("GuiBase") then return SetStatus("Target must be a valid GUI object.",Color3.fromRGB(255,80,80)) end SetStatus("Converting...",Color3.fromRGB(0,225,255)) task.wait() local luaScript=Serializer:Convert(target,path) local timestamp=os.date("%Y-%m-%d_%H-%M-%S") local fileName=string.format("%s - %s (%s).lua",SanitizeForFilename(target.Name),GetGameName(),timestamp) local folder="Gui2Lua"; makefolder(folder); local filePath=folder.."/"..fileName local ok,err=pcall(writefile,filePath,luaScript) if ok then SetStatus("Successfully saved file to: "..getAbsPath()..filePath,Color3.fromRGB(80,255,80)) else SetStatus("Error saving file. Check developer console for details.",Color3.fromRGB(255,80,80)); warn("Gui2Lua Error: "..tostring(err)) end end)) --//========================================================================//-- --// INITIALIZATION & CLEANUP //-- --//========================================================================//-- Gui2Lua.Parent=CoreGui local env=getgenv(); env.Gui2Lua={GUI=Gui2Lua,Cleanup=function() for _,c in ipairs(connections) do c:Disconnect() end; Gui2Lua:Destroy(); env.Gui2Lua=nil end}