TEST n Open Source Gui2Lua gui by Irfannnnn
Key RequiredUniversal

TEST n Open Source Gui2Lua gui by Irfannnnn

Universal ScriptIrfannnnnIrfannnnn 4.8K views 50 executesUpdated Aug 27, 2025
5.0/ 5(2 votes)
20100% Positive
Lua Script•246 lines (17357 chars)
--//========================================================================//--
--//                            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}

Features & Information

This is just a test & open source, so you guys can use it anywhere and edit the scripts.. - Required: Infinite Yield (command: 'dex/explorer'), to copy the ScreenGui path (supported: 'StarterGui', 'PlayerGui' & 'CoreGui'). - Rename copied path from 'game:GetService("CoreGui").<ScreenGui_name>' to 'CoreGui.<ScreenGui_name>' (Example: 'game:GetService("CoreGui").ExperienceChat' to 'CoreGui.ExperienceChat'). - The Localscript toggle works fine if your executor has decompiler in it. - It used XML saving methods & not everything it save, so idk. Credits all to me, thanks! :D
#Gui to Lua#Gui Conversion to Lua#Gui Lua#Gui#Test

Community Comments (3)

v1nnzv1nnzAug 28, 2025

Where's the manga reader silly

Replying to @v1nnz
IrfannnnnIrfannnnnAug 28, 2025

@sleeper i can't make it

What is this script?

More Scripts for Universal Scripts