Spaces:
Sleeping
Sleeping
| --[[ | |
| GildedS v3 — AI Assistant for Roblox Studio | |
| by OmegaOneOfficial | |
| INSTALACIÓN: | |
| 1. Guardá este archivo como "GildedS.lua" | |
| 2. Ponelo en la carpeta de plugins de Roblox Studio: | |
| Windows: %LOCALAPPDATA%\Roblox\Plugins\ | |
| Mac: ~/Documents/Roblox/Plugins/ | |
| 3. Reiniciá Roblox Studio | |
| 4. Activá el widget desde la pestaña Plugins | |
| ]] | |
| -- ============================================ | |
| -- CONFIGURACIÓN | |
| -- ============================================ | |
| local API_URL = "https://OmegaOneOfficial-gildeds.hf.space" | |
| local HttpService = game:GetService("HttpService") | |
| local TweenService = game:GetService("TweenService") | |
| -- ============================================ | |
| -- TOOLBAR | |
| -- ============================================ | |
| local toolbar = plugin:CreateToolbar("GildedS") | |
| local toggleButton = toolbar:CreateButton( | |
| "GildedS", | |
| "Abrir GildedS — Asistente de IA", | |
| "rbxassetid://0" | |
| ) | |
| -- ============================================ | |
| -- WIDGET | |
| -- ============================================ | |
| local widgetInfo = DockWidgetPluginGuiInfo.new( | |
| Enum.InitialDockState.Right, | |
| false, false, | |
| 380, 580, | |
| 300, 420 | |
| ) | |
| local widget = plugin:CreateDockWidgetPluginGui("GildedS_v3", widgetInfo) | |
| widget.Title = "⚡ GildedS" | |
| widget.Enabled = false | |
| -- ============================================ | |
| -- PALETA DE COLORES | |
| -- ============================================ | |
| local C = { | |
| bg = Color3.fromHex("#0d0d10"), | |
| surface = Color3.fromHex("#141417"), | |
| elevated = Color3.fromHex("#1c1c22"), | |
| border = Color3.fromHex("#2a2a32"), | |
| accent = Color3.fromHex("#FFD700"), | |
| accentDim = Color3.fromHex("#B89600"), | |
| textMain = Color3.fromHex("#f0f0f2"), | |
| textSub = Color3.fromHex("#77778a"), | |
| userBg = Color3.fromHex("#161620"), | |
| aiBg = Color3.fromHex("#111118"), | |
| codeBg = Color3.fromHex("#0e0e18"), | |
| error = Color3.fromHex("#FF5555"), | |
| success = Color3.fromHex("#44DD77"), | |
| warn = Color3.fromHex("#FFAA22"), | |
| blue = Color3.fromHex("#7B8FFF"), | |
| } | |
| -- ============================================ | |
| -- MAIN FRAME | |
| -- ============================================ | |
| local mainFrame = Instance.new("Frame") | |
| mainFrame.Size = UDim2.new(1, 0, 1, 0) | |
| mainFrame.BackgroundColor3 = C.bg | |
| mainFrame.BorderSizePixel = 0 | |
| mainFrame.Parent = widget | |
| -- ============================================ | |
| -- HEADER | |
| -- ============================================ | |
| local header = Instance.new("Frame") | |
| header.Size = UDim2.new(1, 0, 0, 50) | |
| header.BackgroundColor3 = C.surface | |
| header.BorderSizePixel = 0 | |
| header.Parent = mainFrame | |
| -- Línea de acento dorada bajo el header | |
| local headerLine = Instance.new("Frame") | |
| headerLine.Size = UDim2.new(1, 0, 0, 2) | |
| headerLine.Position = UDim2.new(0, 0, 1, -2) | |
| headerLine.BackgroundColor3 = C.accent | |
| headerLine.BorderSizePixel = 0 | |
| headerLine.Parent = header | |
| -- Ícono / título | |
| local headerTitle = Instance.new("TextLabel") | |
| headerTitle.Size = UDim2.new(0, 120, 1, 0) | |
| headerTitle.Position = UDim2.new(0, 12, 0, 0) | |
| headerTitle.BackgroundTransparency = 1 | |
| headerTitle.Text = "⚡ GildedS" | |
| headerTitle.TextColor3 = C.accent | |
| headerTitle.TextSize = 17 | |
| headerTitle.Font = Enum.Font.GothamBold | |
| headerTitle.TextXAlignment = Enum.TextXAlignment.Left | |
| headerTitle.Parent = header | |
| -- Status dot | |
| local statusDot = Instance.new("Frame") | |
| statusDot.Size = UDim2.new(0, 8, 0, 8) | |
| statusDot.Position = UDim2.new(1, -114, 0.5, -4) | |
| statusDot.BackgroundColor3 = C.textSub | |
| statusDot.BorderSizePixel = 0 | |
| statusDot.Parent = header | |
| Instance.new("UICorner", statusDot).CornerRadius = UDim.new(1, 0) | |
| local statusLabel = Instance.new("TextLabel") | |
| statusLabel.Size = UDim2.new(0, 100, 1, 0) | |
| statusLabel.Position = UDim2.new(1, -105, 0, 0) | |
| statusLabel.BackgroundTransparency = 1 | |
| statusLabel.Text = "offline" | |
| statusLabel.TextColor3 = C.textSub | |
| statusLabel.TextSize = 11 | |
| statusLabel.Font = Enum.Font.Gotham | |
| statusLabel.TextXAlignment = Enum.TextXAlignment.Left | |
| statusLabel.Parent = header | |
| -- Botón limpiar | |
| local clearBtn = Instance.new("TextButton") | |
| clearBtn.Size = UDim2.new(0, 28, 0, 28) | |
| clearBtn.Position = UDim2.new(1, -36, 0.5, -14) | |
| clearBtn.BackgroundColor3 = C.elevated | |
| clearBtn.Text = "🗑" | |
| clearBtn.TextSize = 13 | |
| clearBtn.Font = Enum.Font.Gotham | |
| clearBtn.TextColor3 = C.textSub | |
| clearBtn.BorderSizePixel = 0 | |
| clearBtn.Parent = header | |
| Instance.new("UICorner", clearBtn).CornerRadius = UDim.new(0, 6) | |
| -- ============================================ | |
| -- BARRA DE OPCIONES | |
| -- ============================================ | |
| local optBar = Instance.new("Frame") | |
| optBar.Size = UDim2.new(1, 0, 0, 34) | |
| optBar.Position = UDim2.new(0, 0, 0, 50) | |
| optBar.BackgroundColor3 = C.surface | |
| optBar.BorderSizePixel = 0 | |
| optBar.Parent = mainFrame | |
| local optBarLine = Instance.new("Frame") | |
| optBarLine.Size = UDim2.new(1, 0, 0, 1) | |
| optBarLine.Position = UDim2.new(0, 0, 1, -1) | |
| optBarLine.BackgroundColor3 = C.border | |
| optBarLine.BorderSizePixel = 0 | |
| optBarLine.Parent = optBar | |
| -- Toggle: ver código antes de ejecutar | |
| local previewToggle = Instance.new("TextButton") | |
| previewToggle.Size = UDim2.new(0, 130, 0, 22) | |
| previewToggle.Position = UDim2.new(0, 10, 0.5, -11) | |
| previewToggle.BackgroundColor3 = C.elevated | |
| previewToggle.Text = "👁 Preview: OFF" | |
| previewToggle.TextColor3 = C.textSub | |
| previewToggle.TextSize = 11 | |
| previewToggle.Font = Enum.Font.Gotham | |
| previewToggle.BorderSizePixel = 0 | |
| previewToggle.Parent = optBar | |
| Instance.new("UICorner", previewToggle).CornerRadius = UDim.new(0, 6) | |
| -- Botón copiar último código | |
| local copyBtn = Instance.new("TextButton") | |
| copyBtn.Size = UDim2.new(0, 120, 0, 22) | |
| copyBtn.Position = UDim2.new(1, -130, 0.5, -11) | |
| copyBtn.BackgroundColor3 = C.elevated | |
| copyBtn.Text = "📋 Copiar código" | |
| copyBtn.TextColor3 = C.textSub | |
| copyBtn.TextSize = 11 | |
| copyBtn.Font = Enum.Font.Gotham | |
| copyBtn.BorderSizePixel = 0 | |
| copyBtn.Parent = optBar | |
| Instance.new("UICorner", copyBtn).CornerRadius = UDim.new(0, 6) | |
| -- ============================================ | |
| -- ÁREA DE CHAT | |
| -- ============================================ | |
| local chatArea = Instance.new("ScrollingFrame") | |
| chatArea.Size = UDim2.new(1, 0, 1, -160) | |
| chatArea.Position = UDim2.new(0, 0, 0, 84) | |
| chatArea.BackgroundTransparency = 1 | |
| chatArea.BorderSizePixel = 0 | |
| chatArea.ScrollBarThickness = 3 | |
| chatArea.ScrollBarImageColor3 = C.accent | |
| chatArea.CanvasSize = UDim2.new(0, 0, 0, 0) | |
| chatArea.AutomaticCanvasSize = Enum.AutomaticSize.Y | |
| chatArea.Parent = mainFrame | |
| local chatPad = Instance.new("UIPadding") | |
| chatPad.PaddingLeft = UDim.new(0, 8) | |
| chatPad.PaddingRight = UDim.new(0, 8) | |
| chatPad.PaddingTop = UDim.new(0, 8) | |
| chatPad.PaddingBottom = UDim.new(0, 6) | |
| chatPad.Parent = chatArea | |
| local chatLayout = Instance.new("UIListLayout") | |
| chatLayout.SortOrder = Enum.SortOrder.LayoutOrder | |
| chatLayout.Padding = UDim.new(0, 6) | |
| chatLayout.Parent = chatArea | |
| -- ============================================ | |
| -- ZONA DE INPUT | |
| -- ============================================ | |
| local inputZone = Instance.new("Frame") | |
| inputZone.Size = UDim2.new(1, 0, 0, 76) | |
| inputZone.Position = UDim2.new(0, 0, 1, -76) | |
| inputZone.BackgroundColor3 = C.surface | |
| inputZone.BorderSizePixel = 0 | |
| inputZone.Parent = mainFrame | |
| local inputZoneLine = Instance.new("Frame") | |
| inputZoneLine.Size = UDim2.new(1, 0, 0, 1) | |
| inputZoneLine.BackgroundColor3 = C.border | |
| inputZoneLine.BorderSizePixel = 0 | |
| inputZoneLine.Parent = inputZone | |
| local inputPad = Instance.new("UIPadding") | |
| inputPad.PaddingLeft = UDim.new(0, 10) | |
| inputPad.PaddingRight = UDim.new(0, 10) | |
| inputPad.PaddingTop = UDim.new(0, 10) | |
| inputPad.PaddingBottom = UDim.new(0, 10) | |
| inputPad.Parent = inputZone | |
| local inputInner = Instance.new("Frame") | |
| inputInner.Size = UDim2.new(1, 0, 1, 0) | |
| inputInner.BackgroundColor3 = C.elevated | |
| inputInner.BorderSizePixel = 0 | |
| inputInner.Parent = inputZone | |
| Instance.new("UICorner", inputInner).CornerRadius = UDim.new(0, 10) | |
| local inputStroke = Instance.new("UIStroke") | |
| inputStroke.Color = C.border | |
| inputStroke.Thickness = 1 | |
| inputStroke.Parent = inputInner | |
| local inputBox = Instance.new("TextBox") | |
| inputBox.Size = UDim2.new(1, -54, 1, -12) | |
| inputBox.Position = UDim2.new(0, 12, 0, 6) | |
| inputBox.BackgroundTransparency = 1 | |
| inputBox.Text = "" | |
| inputBox.PlaceholderText = "Describí qué querés crear..." | |
| inputBox.PlaceholderColor3 = C.textSub | |
| inputBox.TextColor3 = C.textMain | |
| inputBox.TextSize = 13 | |
| inputBox.Font = Enum.Font.Gotham | |
| inputBox.TextXAlignment = Enum.TextXAlignment.Left | |
| inputBox.ClearTextOnFocus = false | |
| inputBox.MultiLine = false | |
| inputBox.Parent = inputInner | |
| local sendBtn = Instance.new("TextButton") | |
| sendBtn.Size = UDim2.new(0, 36, 0, 36) | |
| sendBtn.Position = UDim2.new(1, -42, 0.5, -18) | |
| sendBtn.BackgroundColor3 = C.accent | |
| sendBtn.Text = "↑" | |
| sendBtn.TextColor3 = Color3.fromHex("#0a0a0c") | |
| sendBtn.TextSize = 20 | |
| sendBtn.Font = Enum.Font.GothamBold | |
| sendBtn.BorderSizePixel = 0 | |
| sendBtn.Parent = inputInner | |
| Instance.new("UICorner", sendBtn).CornerRadius = UDim.new(0, 8) | |
| -- ============================================ | |
| -- ESTADO INTERNO | |
| -- ============================================ | |
| local messageOrder = 0 | |
| local conversationId = HttpService:GenerateGUID(false) | |
| local isProcessing = false | |
| local previewMode = false | |
| local lastCode = "" | |
| -- ============================================ | |
| -- HELPERS DE UI | |
| -- ============================================ | |
| local function setStatus(state) | |
| local configs = { | |
| online = { color = C.success, text = "online" }, | |
| processing = { color = C.warn, text = "pensando..." }, | |
| error = { color = C.error, text = "error" }, | |
| offline = { color = C.textSub, text = "offline" }, | |
| } | |
| local cfg = configs[state] or configs.offline | |
| statusDot.BackgroundColor3 = cfg.color | |
| statusLabel.Text = cfg.text | |
| statusLabel.TextColor3 = cfg.color | |
| end | |
| local function scrollBottom() | |
| task.wait(0.06) | |
| chatArea.CanvasPosition = Vector2.new(0, chatArea.AbsoluteCanvasSize.Y) | |
| end | |
| local function addMessage(text, msgType) | |
| -- tipos: "user", "ai", "success", "error", "warn", "code" | |
| msgType = msgType or "ai" | |
| messageOrder = messageOrder + 1 | |
| local styles = { | |
| user = { bg = C.userBg, name = "Vos", nameColor = C.blue, textColor = C.textMain }, | |
| ai = { bg = C.aiBg, name = "⚡ GildedS", nameColor = C.accent, textColor = C.textMain }, | |
| success = { bg = C.aiBg, name = "⚡ GildedS", nameColor = C.success, textColor = C.textMain }, | |
| error = { bg = Color3.fromHex("#150d0d"), name = "⚡ GildedS", nameColor = C.error, textColor = Color3.fromHex("#ffbbbb") }, | |
| warn = { bg = C.aiBg, name = "⚡ GildedS", nameColor = C.warn, textColor = C.textMain }, | |
| code = { bg = C.codeBg, name = "📄 Código", nameColor = Color3.fromHex("#AAAAFF"), textColor = Color3.fromHex("#ccccff") }, | |
| } | |
| local s = styles[msgType] or styles.ai | |
| local frame = Instance.new("Frame") | |
| frame.Size = UDim2.new(1, 0, 0, 0) | |
| frame.AutomaticSize = Enum.AutomaticSize.Y | |
| frame.BackgroundColor3 = s.bg | |
| frame.BorderSizePixel = 0 | |
| frame.LayoutOrder = messageOrder | |
| frame.Parent = chatArea | |
| Instance.new("UICorner", frame).CornerRadius = UDim.new(0, 8) | |
| -- Barra lateral de color | |
| local bar = Instance.new("Frame") | |
| bar.Size = UDim2.new(0, 2, 1, 0) | |
| bar.BackgroundColor3 = s.nameColor | |
| bar.BorderSizePixel = 0 | |
| bar.ZIndex = 2 | |
| bar.Parent = frame | |
| Instance.new("UICorner", bar).CornerRadius = UDim.new(0, 2) | |
| local pad = Instance.new("UIPadding") | |
| pad.PaddingTop = UDim.new(0, 7) | |
| pad.PaddingBottom = UDim.new(0, 8) | |
| pad.PaddingLeft = UDim.new(0, 12) | |
| pad.PaddingRight = UDim.new(0, 10) | |
| pad.Parent = frame | |
| local nameL = Instance.new("TextLabel") | |
| nameL.Size = UDim2.new(1, 0, 0, 14) | |
| nameL.BackgroundTransparency = 1 | |
| nameL.Text = s.name | |
| nameL.TextColor3 = s.nameColor | |
| nameL.TextSize = 11 | |
| nameL.Font = Enum.Font.GothamBold | |
| nameL.TextXAlignment = Enum.TextXAlignment.Left | |
| nameL.Parent = frame | |
| local msgL = Instance.new("TextLabel") | |
| msgL.Size = UDim2.new(1, 0, 0, 0) | |
| msgL.Position = UDim2.new(0, 0, 0, 16) | |
| msgL.AutomaticSize = Enum.AutomaticSize.Y | |
| msgL.BackgroundTransparency = 1 | |
| msgL.Text = text | |
| msgL.TextColor3 = s.textColor | |
| msgL.TextSize = 13 | |
| msgL.Font = msgType == "code" and Enum.Font.RobotoMono or Enum.Font.Gotham | |
| msgL.TextXAlignment = Enum.TextXAlignment.Left | |
| msgL.TextWrapped = true | |
| msgL.Parent = frame | |
| scrollBottom() | |
| return frame | |
| end | |
| local function removeMessage(frame) | |
| if frame and frame.Parent then | |
| messageOrder = messageOrder - 1 | |
| frame:Destroy() | |
| end | |
| end | |
| local function clearChat() | |
| for _, child in ipairs(chatArea:GetChildren()) do | |
| if child:IsA("Frame") then child:Destroy() end | |
| end | |
| messageOrder = 0 | |
| conversationId = HttpService:GenerateGUID(false) | |
| addMessage("Chat limpiado 🧹 Nueva sesión iniciada.\n\n¿Qué construimos?", "ai") | |
| end | |
| local function executeCode(code) | |
| local ok, err = pcall(function() | |
| local fn = loadstring(code) | |
| if fn then fn() end | |
| end) | |
| return ok, err | |
| end | |
| -- ============================================ | |
| -- ENVIAR MENSAJE | |
| -- ============================================ | |
| local function sendMessage() | |
| if isProcessing then return end | |
| local prompt = inputBox.Text | |
| if not prompt or prompt == "" then return end | |
| isProcessing = true | |
| inputBox.Text = "" | |
| sendBtn.BackgroundColor3 = C.accentDim | |
| setStatus("processing") | |
| addMessage(prompt, "user") | |
| -- Loading animado | |
| local loadFrame = addMessage("⏳ Pensando", "ai") | |
| local loadLabel = loadFrame and loadFrame:FindFirstChildWhichIsA("TextLabel", true) | |
| local animRunning = true | |
| task.spawn(function() | |
| local dots = 0 | |
| while animRunning and loadLabel and loadLabel.Parent do | |
| dots = (dots % 4) + 1 | |
| loadLabel.Text = "⏳ Pensando" .. string.rep(".", dots) | |
| task.wait(0.35) | |
| end | |
| end) | |
| -- Request | |
| local ok, response = pcall(function() | |
| return HttpService:RequestAsync({ | |
| Url = API_URL .. "/api/generate", | |
| Method = "POST", | |
| Headers = { ["Content-Type"] = "application/json" }, | |
| Body = HttpService:JSONEncode({ | |
| prompt = prompt, | |
| conversation_id = conversationId | |
| }) | |
| }) | |
| end) | |
| animRunning = false | |
| removeMessage(loadFrame) | |
| if ok and response.Success then | |
| local data = HttpService:JSONDecode(response.Body) | |
| setStatus("online") | |
| if data.is_code and data.code ~= "" then | |
| lastCode = data.code | |
| if previewMode then | |
| local preview = string.sub(data.code, 1, 500) | |
| if #data.code > 500 then preview = preview .. "\n\n[... " .. #data.code .. " chars total]" end | |
| addMessage(preview, "code") | |
| end | |
| local execOk, execErr = executeCode(data.code) | |
| if execOk then | |
| addMessage("✅ " .. data.message, "success") | |
| else | |
| addMessage("⚠️ Error al ejecutar:\n" .. tostring(execErr), "error") | |
| end | |
| else | |
| addMessage(data.message, "ai") | |
| end | |
| else | |
| setStatus("error") | |
| if not ok then | |
| addMessage("❌ Sin conexión. ¿Está activo el HF Space?", "error") | |
| else | |
| addMessage("❌ Error del servidor (HTTP " .. tostring(response.StatusCode) .. ")", "error") | |
| end | |
| end | |
| sendBtn.BackgroundColor3 = C.accent | |
| isProcessing = false | |
| end | |
| -- ============================================ | |
| -- EVENTOS | |
| -- ============================================ | |
| toggleButton.Click:Connect(function() | |
| widget.Enabled = not widget.Enabled | |
| end) | |
| sendBtn.MouseButton1Click:Connect(sendMessage) | |
| inputBox.Focused:Connect(function() | |
| TweenService:Create(inputStroke, TweenInfo.new(0.15), {Color = C.accent}):Play() | |
| end) | |
| inputBox.FocusLost:Connect(function(enter) | |
| TweenService:Create(inputStroke, TweenInfo.new(0.15), {Color = C.border}):Play() | |
| if enter then sendMessage() end | |
| end) | |
| clearBtn.MouseButton1Click:Connect(clearChat) | |
| previewToggle.MouseButton1Click:Connect(function() | |
| previewMode = not previewMode | |
| if previewMode then | |
| previewToggle.Text = "👁 Preview: ON" | |
| previewToggle.TextColor3 = C.accent | |
| previewToggle.BackgroundColor3 = Color3.fromHex("#252510") | |
| else | |
| previewToggle.Text = "👁 Preview: OFF" | |
| previewToggle.TextColor3 = C.textSub | |
| previewToggle.BackgroundColor3 = C.elevated | |
| end | |
| end) | |
| copyBtn.MouseButton1Click:Connect(function() | |
| if lastCode ~= "" then | |
| local sv = Instance.new("StringValue") | |
| sv.Name = "GildedS_LastCode" | |
| sv.Value = lastCode | |
| sv.Parent = game.ReplicatedStorage | |
| addMessage("📋 Código guardado en ReplicatedStorage > GildedS_LastCode\n(Seleccionalo y copiá el Value)", "ai") | |
| else | |
| addMessage("Todavía no generaste ningún código.", "warn") | |
| end | |
| end) | |
| -- Hover effects | |
| sendBtn.MouseEnter:Connect(function() | |
| if not isProcessing then | |
| TweenService:Create(sendBtn, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromHex("#FFE840")}):Play() | |
| end | |
| end) | |
| sendBtn.MouseLeave:Connect(function() | |
| if not isProcessing then | |
| TweenService:Create(sendBtn, TweenInfo.new(0.1), {BackgroundColor3 = C.accent}):Play() | |
| end | |
| end) | |
| clearBtn.MouseEnter:Connect(function() | |
| TweenService:Create(clearBtn, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromHex("#2a1010")}):Play() | |
| end) | |
| clearBtn.MouseLeave:Connect(function() | |
| TweenService:Create(clearBtn, TweenInfo.new(0.1), {BackgroundColor3 = C.elevated}):Play() | |
| end) | |
| -- ============================================ | |
| -- INICIO | |
| -- ============================================ | |
| setStatus("online") | |
| addMessage("¡Hola! 👋 Soy GildedS v3.\n\nDecime qué querés construir:\n• \"Haceme una casa medieval con jardín\"\n• \"Creá una espada mágica\"\n• \"Agregá un sistema de tienda con UI\"\n\nTip: activá 👁 Preview para ver el código antes de ejecutarlo.", "ai") | |
| print("⚡ GildedS v3 Plugin cargado") |