Aprende a crear interfaces modernas para tus scripts de Roblox con nuestra librería completa. Sistema de auto-guardado de temas, compatibilidad móvil y PC, y más de 24 temas disponibles.
Para comenzar a usar JmodsLib, carga la librería desde nuestro repositorio:
--- Esto carga la interfaz/JmodsLib puede ser remplazado por el nombre que deseen
local JmodsLib = loadstring(game:HttpGet('https://raw.githubusercontent.com/pruebasjoao/test/refs/heads/main/JmodsLibV1.0'))()
Puedes cambiar "JmodsLib" por cualquier nombre que prefieras, pero recuerda usar el mismo nombre en todo tu código.
Crea la ventana principal de tu interfaz con todas las opciones personalizables:
--- En JmodsLib ponemos exactamente el mismo nombre que hayamos puesto si es que lo cambiamos anteriormente
local Window = JmodsLib:CreateWindow({
Name = "Mi primera Interfaz",
Icon = 90692784970350, --- Cambiar por el ícono que prefieras
LoadingTitle = "Cargando... espera...", --- Cambiar si quieres algo personalizado
LoadingSubtitle = "ya casi está", --- Cambiar si quieres algo personalizado
Theme = "Rojo", --- Este tema es el tema por defecto que la gente verá al ejecutar tu script
OpenButtomImage = 127271155083726, --- Esto es e boton para abrir en movil, pero es opcional
Intro = true, --- Esto activa la intro pero es opcional
IntroIcon = 90692784970350, --- Esto es el ícono de la intro
AnimationIntro = 5, --- Acá puedes poner del 0 al 6, el 0 siendo random
DragImage = 127271155083726 --- esta es el ícono de abajo a la derecha
})
Si no activas Intro = true, no es necesario lo siguiente y lo puedes eliminar:
Puedes elegir entre 6 animaciones diferentes para la intro:
JmodsLib incluye 24 temas diferentes que se guardan automáticamente. Puedes usar nombres en español o inglés:
| Español | Inglés | Preview | Descripción |
|---|---|---|---|
| negro | black | Tema por defecto | |
| azul | Azul | Azul clásico | |
| oscuro | dark | Gris oscuro moderno | |
| rojo | red | Rojo intenso | |
| verde | green | Verde natural | |
| morado | purple | Morado elegante | |
| naranja | orange | Naranja vibrante | |
| rosa | pink | Rosa moderno | |
| gris | gray | Gris neutro | |
| cian | cyan | Cian fresco | |
| amarillo | yellow | Amarillo dorado | |
| turquesa | turquoise | Turquesa tropical | |
| marron | brown | Marrón tierra | |
| dorado | gold | Oro brillante | |
| plateado | silver | Plata metálica | |
| 🌈 Temas Neón | |||
| neon | neon | Neón estándar | |
| oscuro neon | dark_neon | Neón púrpura | |
| neon azul | neon_blue | Neón azul eléctrico | |
| neon rojo | neon_red | Neón rojo intenso | |
| neon verde | neon_green | Neón verde brillante | |
| neon amarillo | neon_yellow | Neón amarillo | |
| neon rosa | neon_pink | Neón rosa | |
| neon naranja | neon_orange | Neón naranja | |
| neon violeta | neon_violet | Neón violeta | |
| neon blanco | neon_white | Neón blanco puro | |
Los temas se guardan automáticamente y se cargan la próxima vez que ejecutes el script. Los usuarios pueden cambiar el tema usando el selector integrado en la interfaz.
Crea notificaciones atractivas con soporte para links clickeables y detección automática de URLs:
--- Creación de notificaciones
JmodsLib:Notify({
Title = "Bienvenido", --- Título
Content = "joao_mods te espera en https://youtube.com", --- Sí acá se puede poner links, esto es el contenido
Duration = 15, --- Esta es la duración
Image = 13458017478 --- Esta imagen se mostrará a la esquina derecha de la notificación
})
JmodsLib:Notify({
Title = "Script Cargado",
Content = "¡Todo listo para usar!",
Duration = 3
})
JmodsLib:Notify({
Title = "Únete al Discord",
Content = "Discord: https://discord.gg/ZTVC94ZmVZ",
Duration = 10,
Image = 13458017478
})
Los tabs te permiten organizar tu interfaz en diferentes páginas. Cada tab puede contener múltiples elementos:
--- Creación de tabs:
MainTab = Window:CreateTab("Principal")
--- Crear un segundo tab
SettingsTab = Window:CreateTab("Configuración")
--- Crear un tercer tab
ScriptsTab = Window:CreateTab("Scripts")
El nombre que le pongas a la variable (ej. MainTab, SettingsTab) será lo que uses para referenciar ese tab cuando agregues elementos. Puedes crear tantos tabs como necesites.
Las secciones actúan como separadores visuales y organizadores dentro de los tabs:
--- Sección con título
Section1 = MainTab:CreateSection("Funciones Principales")
--- Sección vacía como separador
Separator = MainTab:CreateSection("")
--- Otra sección
Section2 = MainTab:CreateSection("Configuración Avanzada")
Los botones ejecutan funciones cuando son presionados:
--- Botón básico
Button1 = MainTab:CreateButton({
Name = "Saludar",
Callback = function()
print("¡Hola mundo!")
JmodsLib:Notify({
Title = "Saludos",
Content = "¡Hola desde el botón!",
Duration = 3
})
end
})
--- Botón que ejecuta script externo
Button2 = MainTab:CreateButton({
Name = "Cargar Script",
Callback = function()
loadstring(game:HttpGet("https://example.com/script.lua"))()
end
})
Los toggles permiten activar/desactivar funciones:
MainTab:CreateToggle({
Name = "Auto Farm",
CurrentValue = false, --- Valor inicial
Callback = function(state)
if state then
print("Auto Farm activado")
-- Aquí iría la lógica del auto farm
else
print("Auto Farm desactivado")
-- Aquí iría la lógica para detener el auto farm
end
end
})
Los sliders controlan valores numéricos dentro de un rango:
MainTab:CreateSlider({
Name = "Velocidad de Caminata",
Range = {16, 100}, --- Mínimo y máximo
Increment = 1, --- De cuánto en cuánto cambia
Suffix = "studs/s", --- Texto después del valor
CurrentValue = 16, --- Valor inicial
Callback = function(value)
print("Velocidad cambiada a:", value)
if game.Players.LocalPlayer.Character and game.Players.LocalPlayer.Character:FindFirstChild("Humanoid") then
game.Players.LocalPlayer.Character.Humanoid.WalkSpeed = value
end
end
})
Los inputs permiten al usuario escribir texto:
MainTab:CreateInput({
Name = "Nombre del Jugador",
PlaceholderText = "Escribe un nombre...",
Callback = function(text)
print("Texto ingresado:", text)
-- Ejemplo: buscar jugador por nombre
local player = game.Players:FindFirstChild(text)
if player then
JmodsLib:Notify({
Title = "Jugador encontrado",
Content = "Encontrado: " .. player.Name,
Duration = 3
})
end
end
})
Los dropdowns permiten seleccionar entre múltiples opciones predefinidas:
MainTab:CreateDropdown({
Name = "Seleccionar Arma",
Options = {"Espada", "Arco", "Hacha", "Lanza"},
Callback = function(option)
print("Arma seleccionada:", option)
-- Aquí podrías equipar el arma seleccionada
end
})
Los colorpickers permiten seleccionar colores con una interfaz visual:
MainTab:CreateColorPicker({
Name = "Color del Aura",
Color = Color3.fromRGB(255, 0, 0), --- Color inicial
Callback = function(color)
print(string.format("Color seleccionado: RGB(%d, %d, %d)",
color.R*255, color.G*255, color.B*255))
-- Aquí podrías aplicar el color a algún efecto visual
end
})
Los keybinds permiten asignar teclas para activar funciones rápidamente:
MainTab:CreateKeybind({
Name = "Toggle Fly",
CurrentKeybind = "F", --- Tecla inicial
Callback = function(key)
print("Tecla presionada:", key)
-- Aquí iría la lógica para activar/desactivar fly
JmodsLib:Notify({
Title = "Fly Toggle",
Content = "Fly activado/desactivado",
Duration = 2
})
end
})
Los paragraphs muestran información, créditos o instrucciones:
--- Información básica
MainTab:CreateParagraph({
Title = "Información",
Content = "Este script fue creado por joao_mods. Versión 1.0"
})
--- Instrucciones de uso
MainTab:CreateParagraph({
Title = "Instrucciones",
Content = "1. Activa Auto Farm\n2. Ajusta la velocidad\n3. Presiona F para volar"
})
Puedes cambiar temas desde tu código y obtener información sobre el tema actual:
--- Cambiar tema programáticamente
Window:SetTheme("neon_blue")
--- Obtener el tema actual
local currentTheme = Window:GetCurrentTheme()
print("Tema actual:", currentTheme)
--- Obtener información completa del sistema de temas
local themeInfo = JmodsLib:GetThemeInfo()
print("Información de temas:", themeInfo)
Puedes cambiar la tecla que minimiza/restaura la interfaz:
--- Cambiar la tecla de minimizado a M
Window:SetRestoreKey(Enum.KeyCode.M)
--- Cambiar a Insert
Window:SetRestoreKey(Enum.KeyCode.Insert)
Resetea el sistema de temas al valor por defecto:
--- Resetear tema al por defecto (negro)
JmodsLib:ResetTheme()
El Dropdown de JmodsLib incluye métodos avanzados para actualizar las opciones de forma dinámica durante la ejecución del script:
Primero, crea el dropdown y guarda su referencia en una variable:
--- Crear dropdown y guardar referencia
local MiDropdown = MainTab:CreateDropdown({
Name = "Seleccionar Jugador",
Options = {"Jugador1", "Jugador2", "Jugador3"},
Callback = function(selected)
print("Jugador seleccionado:", selected)
end
})
Debes guardar el dropdown en una variable (ej. MiDropdown) para poder usar sus métodos posteriormente.
Este método actualiza las opciones del dropdown inmediatamente, incluso si el dropdown está abierto:
--- Actualización inmediata de opciones
MiDropdown:UpdateOptions({"NuevaOpcion1", "NuevaOpcion2", "NuevaOpcion3"})
--- Ejemplo práctico: Actualizar lista de jugadores en tiempo real
local function actualizarJugadores()
local jugadores = {}
for _, player in pairs(game.Players:GetPlayers()) do
table.insert(jugadores, player.Name)
end
MiDropdown:UpdateOptions(jugadores)
end
--- Actualizar cada 5 segundos
spawn(function()
while true do
wait(5)
actualizarJugadores()
end
end)
Este método programa una actualización que solo se aplicará cuando el usuario cierre el dropdown:
--- Actualización diferida (cuando se cierre el dropdown)
MiDropdown:UpdateOnClose({"Opcion1", "Opcion2", "Opcion3"})
--- Ejemplo práctico: Escaneo de NPCs sin interrumpir al usuario
local NPCDropdown = MainTab:CreateDropdown({
Name = "Seleccionar NPC",
Options = {"Escaneando..."},
Callback = function(npc)
print("NPC seleccionado:", npc)
end
})
--- Función que escanea NPCs constantemente
spawn(function()
while true do
wait(2)
--- Buscar todos los NPCs en el Workspace
local npcs = {}
for _, npc in pairs(workspace.NPCs:GetChildren()) do
if npc:FindFirstChild("Humanoid") then
table.insert(npcs, npc.Name)
end
end
--- Programar actualización (no interrumpe si está abierto)
NPCDropdown:UpdateOnClose(npcs)
end
end)
| Característica | UpdateOptions() | UpdateOnClose() |
|---|---|---|
| Momento de aplicación | Inmediato | Al cerrar dropdown |
| Cierra el dropdown? | Sí, siempre | No, respeta la interacción |
| Interrumpe al usuario? | Sí, si está seleccionando | No, espera a que termine |
| Mejor para... | Botones, eventos únicos | Loops, escaneos continuos |
| Ejemplo de uso | Cambiar mapa actual | Lista de jugadores en vivo |
Cambia la opción seleccionada actualmente (no modifica la lista de opciones):
--- Cambiar la selección actual
MiDropdown:Set("Jugador2")
--- Ejemplo: Seleccionar automáticamente al jugador más cercano
local function seleccionarMasCercano()
local player = game.Players.LocalPlayer
local char = player.Character
if not char or not char:FindFirstChild("HumanoidRootPart") then return end
local pos = char.HumanoidRootPart.Position
local closest = nil
local minDist = math.huge
for _, p in pairs(game.Players:GetPlayers()) do
if p ~= player and p.Character and p.Character:FindFirstChild("HumanoidRootPart") then
local dist = (p.Character.HumanoidRootPart.Position - pos).Magnitude
if dist < minDist then
minDist = dist
closest = p.Name
end
end
end
if closest then
MiDropdown:Set(closest)
JmodsLib:Notify({
Title = "Jugador Más Cercano",
Content = "Seleccionado: " .. closest,
Duration = 3
})
end
end
Obtiene el valor actualmente seleccionado en el dropdown:
--- Obtener la opción seleccionada
local seleccion = MiDropdown:Get()
print("Opción actual:", seleccion)
--- Ejemplo: Botón que usa la selección actual
MainTab:CreateButton({
Name = "Teleport al Jugador",
Callback = function()
local targetName = MiDropdown:Get()
local target = game.Players:FindFirstChild(targetName)
if target and target.Character then
local myChar = game.Players.LocalPlayer.Character
if myChar and myChar:FindFirstChild("HumanoidRootPart") then
myChar.HumanoidRootPart.CFrame = target.Character.HumanoidRootPart.CFrame
end
end
end
})
--- Dropdown con actualización continua
local JugadorDropdown = MainTab:CreateDropdown({
Name = "Jugadores (Auto-actualiza)",
Options = {"Cargando..."},
Callback = function(jugador)
print("Seleccionado:", jugador)
end
})
--- Loop de actualización cada 3 segundos
spawn(function()
while true do
wait(3)
local jugadores = {}
for _, p in pairs(game.Players:GetPlayers()) do
table.insert(jugadores, p.Name)
end
--- Usar UpdateOnClose para no interrumpir
JugadorDropdown:UpdateOnClose(jugadores)
end
end)
--- Dropdown de armas
local ArmaDropdown = MainTab:CreateDropdown({
Name = "Seleccionar Arma",
Options = {"Espada", "Arco"},
Callback = function(arma)
print("Arma:", arma)
end
})
--- Botón para actualizar armas disponibles
MainTab:CreateButton({
Name = "Escanear Armas",
Callback = function()
local armas = {}
--- Buscar armas en el inventario
local backpack = game.Players.LocalPlayer.Backpack
for _, tool in pairs(backpack:GetChildren()) do
table.insert(armas, tool.Name)
end
--- Actualizar inmediatamente
ArmaDropdown:UpdateOptions(armas)
JmodsLib:Notify({
Title = "Escaneo Completo",
Content = "Encontradas " .. #armas .. " armas",
Duration = 3
})
end
})
--- Dropdown principal
local TipoDropdown = MainTab:CreateDropdown({
Name = "Tipo de Mob",
Options = {"Todos", "Jefes", "Normales"},
Callback = function(tipo)
--- Actualizar el segundo dropdown según el tipo
local mobs = {}
if tipo == "Jefes" then
mobs = {"Boss1", "Boss2", "Boss3"}
elseif tipo == "Normales" then
mobs = {"Mob1", "Mob2", "Mob3"}
else
mobs = {"Todos los mobs..."}
end
MobDropdown:UpdateOptions(mobs)
end
})
--- Dropdown secundario (se actualiza según el primero)
local MobDropdown = MainTab:CreateDropdown({
Name = "Seleccionar Mob",
Options = {"Selecciona un tipo primero"},
Callback = function(mob)
print("Mob objetivo:", mob)
end
})
pcall() si los datos pueden fallar--- RESUMEN DE TODOS LOS MÉTODOS DEL DROPDOWN
--- 1. Crear dropdown (guardar referencia)
local dropdown = Tab:CreateDropdown({...})
--- 2. Actualizar opciones inmediatamente
dropdown:UpdateOptions({"op1", "op2", "op3"})
--- 3. Programar actualización al cerrar
dropdown:UpdateOnClose({"op1", "op2", "op3"})
--- 4. Cambiar la selección actual
dropdown:Set("op2")
--- 5. Obtener la selección actual
local actual = dropdown:Get()
print(actual) --- Imprime: "op2"
Aquí tienes un script completo que demuestra todas las funcionalidades de JmodsLib:
--- JmodsLib
--- Cargar la librería
local JmodsLib = loadstring(game:HttpGet('https://raw.githubusercontent.com/pruebasjoao/test/refs/heads/main/JmodsLibV1.0'))()
--- Crear la ventana principal
local Window = JmodsLib:CreateWindow({
Name = "Mi Script Completo",
Icon = 90692784970350,
LoadingTitle = "Cargando Script...",
LoadingSubtitle = "Inicializando componentes...",
Theme = "neon_blue",
Intro = true,
IntroIcon = 90692784970350,
AnimationIntro = 0, --- Animación aleatoria
DragImage = 127271155083726
})
--- Notificación de bienvenida
JmodsLib:Notify({
Title = "¡Bienvenido!",
Content = "Script cargado correctamente. Discord: https://discord.gg/ZTVC94ZmVZ",
Duration = 8,
Image = 13458017478
})
--- 📑 CREAR TABS
local MainTab = Window:CreateTab("Principal")
local PlayerTab = Window:CreateTab("Jugador")
local ScriptsTab = Window:CreateTab("Scripts")
local SettingsTab = Window:CreateTab("Configuración")
--- 📋 TAB PRINCIPAL
MainTab:CreateSection("Información del Script")
MainTab:CreateParagraph({
Title = "Script Universal",
Content = "Este es un ejemplo completo de JmodsLib. Incluye todas las funcionalidades disponibles."
})
MainTab:CreateButton({
Name = "Mostrar Información",
Callback = function()
local player = game.Players.LocalPlayer
JmodsLib:Notify({
Title = "Tu Información",
Content = string.format("Jugador: %s\nUserID: %d\nCuenta creada: %s",
player.Name,
player.UserId,
os.date("%Y-%m-%d", player.AccountAge * 86400)
),
Duration = 6
})
end
})
MainTab:CreateSection("") --- Separador
--- 🎮 TAB JUGADOR
PlayerTab:CreateSection("Modificadores del Jugador")
--- Variables para estados
local flyEnabled = false
local noClipEnabled = false
--- Slider de velocidad de caminata
PlayerTab:CreateSlider({
Name = "Velocidad de Caminata",
Range = {16, 200},
Increment = 1,
Suffix = " studs/s",
CurrentValue = 16,
Callback = function(value)
local char = game.Players.LocalPlayer.Character
if char and char:FindFirstChild("Humanoid") then
char.Humanoid.WalkSpeed = value
end
end
})
--- Slider de poder de salto
PlayerTab:CreateSlider({
Name = "Poder de Salto",
Range = {50, 500},
Increment = 5,
Suffix = " poder",
CurrentValue = 50,
Callback = function(value)
local char = game.Players.LocalPlayer.Character
if char and char:FindFirstChild("Humanoid") then
char.Humanoid.JumpPower = value
end
end
})
--- Toggle para Fly
PlayerTab:CreateToggle({
Name = "Fly Mode",
CurrentValue = false,
Callback = function(state)
flyEnabled = state
if state then
JmodsLib:Notify({
Title = "Fly Activado",
Content = "Usa WASD para volar, Space/Shift para subir/bajar",
Duration = 4
})
--- Aquí iría la lógica del fly
else
JmodsLib:Notify({
Title = "Fly Desactivado",
Content = "Modo vuelo deshabilitado",
Duration = 2
})
end
end
})
--- Input para teletransporte
PlayerTab:CreateInput({
Name = "Teleport a Jugador",
PlaceholderText = "Nombre del jugador...",
Callback = function(playerName)
local targetPlayer = game.Players:FindFirstChild(playerName)
if targetPlayer and targetPlayer.Character and targetPlayer.Character:FindFirstChild("HumanoidRootPart") then
local myChar = game.Players.LocalPlayer.Character
if myChar and myChar:FindFirstChild("HumanoidRootPart") then
myChar.HumanoidRootPart.CFrame = targetPlayer.Character.HumanoidRootPart.CFrame
JmodsLib:Notify({
Title = "Teleport Exitoso",
Content = "Te teletransportaste a " .. targetPlayer.Name,
Duration = 3
})
end
else
JmodsLib:Notify({
Title = "Error",
Content = "Jugador no encontrado: " .. playerName,
Duration = 3
})
end
end
})
--- 🛠️ TAB SCRIPTS
ScriptsTab:CreateSection("Scripts Externos")
ScriptsTab:CreateButton({
Name = "Infinite Yield",
Callback = function()
loadstring(game:HttpGet('https://raw.githubusercontent.com/EdgeIY/infiniteyield/master/source'))()
JmodsLib:Notify({
Title = "Script Cargado",
Content = "Infinite Yield cargado exitosamente",
Duration = 3
})
end
})
ScriptsTab:CreateButton({
Name = "Dex Explorer",
Callback = function()
loadstring(game:HttpGet("https://raw.githubusercontent.com/infyiff/backup/main/dex.lua"))()
end
})
ScriptsTab:CreateDropdown({
Name = "Scripts de Juegos",
Options = {"Arsenal", "Adopt Me", "Blox Fruits", "Tower Defense Simulator"},
Callback = function(game)
JmodsLib:Notify({
Title = "Script de Juego",
Content = "Cargando script para: " .. game,
Duration = 3
})
--- Aquí cargarías el script específico del juego
end
})
--- ⚙️ TAB CONFIGURACIÓN
SettingsTab:CreateSection("Configuración de la Interfaz")
SettingsTab:CreateParagraph({
Title = "Control de Temas",
Content = "Los temas se guardan automáticamente. Usa el botón de paleta en la barra superior para cambiar temas."
})
SettingsTab:CreateButton({
Name = "Cambiar a Tema Aleatorio",
Callback = function()
local themes = {"red", "green", "blue", "purple", "neon", "neon_blue", "neon_pink"}
local randomTheme = themes[math.random(1, #themes)]
Window:SetTheme(randomTheme)
JmodsLib:Notify({
Title = "Tema Cambiado",
Content = "Nuevo tema aplicado: " .. randomTheme,
Duration = 4
})
end
})
SettingsTab:CreateColorPicker({
Name = "Color de Ejemplo",
Color = Color3.fromRGB(255, 100, 100),
Callback = function(color)
print(string.format("Color RGB: %d, %d, %d",
color.R*255, color.G*255, color.B*255))
end
})
SettingsTab:CreateKeybind({
Name = "Hotkey de Ejemplo",
CurrentKeybind = "G",
Callback = function(key)
JmodsLib:Notify({
Title = "Hotkey Activado",
Content = "Presionaste: " .. key.Name,
Duration = 2
})
end
})
SettingsTab:CreateSection("Créditos")
SettingsTab:CreateParagraph({
Title = "Desarrollado por",
Content = "joao_mods - JmodsLib v1.0\nGracias por usar nuestro script!"
})
--- 📱 CONFIGURACIONES FINALES
--- Cambiar la tecla de minimizado (opcional)
Window:SetRestoreKey(Enum.KeyCode.Insert)
--- Notificación final
wait(2)
JmodsLib:Notify({
Title = "¡Script Listo!",
Content = "Todas las funciones cargadas. Presiona INSERT para minimizar.",
Duration = 5
})
Ejemplos de cómo adaptar JmodsLib para juegos específicos de Roblox:
--- Script específico para Arsenal
local ArsenalTab = Window:CreateTab("Arsenal")
ArsenalTab:CreateToggle({
Name = "Aimbot",
CurrentValue = false,
Callback = function(state)
print("Aimbot:", state)
--- Lógica del aimbot aquí
end
})
ArsenalTab:CreateSlider({
Name = "FOV del Aimbot",
Range = {50, 360},
CurrentValue = 120,
Suffix = "°",
Callback = function(value)
print("FOV cambiado a:", value)
end
})
--- Script específico para Blox Fruits
local BloxTab = Window:CreateTab("Blox Fruits")
BloxTab:CreateToggle({
Name = "Auto Farm",
CurrentValue = false,
Callback = function(state)
if state then
JmodsLib:Notify({
Title = "Auto Farm",
Content = "Auto Farm activado para Blox Fruits",
Duration = 3
})
end
end
})
BloxTab:CreateDropdown({
Name = "Seleccionar Fruta",
Options = {"Rubber", "Fire", "Ice", "Dark", "Light"},
Callback = function(fruit)
print("Fruta seleccionada:", fruit)
end
})
Intro = false, puedes eliminar: LoadingTitle, LoadingSubtitle, IntroIcon, AnimationIntroSiempre verifica que los objetos existan antes de usarlos:
local char = game.Players.LocalPlayer.Character
if char and char:FindFirstChild("Humanoid") then
char.Humanoid.WalkSpeed = 50
end
Verifica que estés referenciando el tab correcto:
--- ❌ Incorrecto
WrongTab:CreateButton({...})
--- ✅ Correcto
MainTab:CreateButton({...})
Asegúrate de que la sintaxis del callback sea correcta:
--- ✅ Correcto
Callback = function(value)
print(value)
end