Esa tabla que sale al pulsar Tab con el nombre de cada jugador y sus puntos no es un objeto que se pone desde Studio: es una carpeta dentro del jugador. Si la creas con el nombre exacto que Roblox espera, la tabla aparece sola. Si te equivocas en una letra, no aparece nada y no hay error en la consola.
En la demo de abajo eliges qué columnas quieres y te genera el script listo para pegar.
Respuesta rápida
Crea una carpeta llamada leaderstats dentro del jugador y mete dentro un IntValue por cada columna. Roblox detecta esa carpeta y dibuja la tabla automáticamente. El nombre tiene que ser exactamente leaderstats, en minúsculas y sin espacio.
Lo que necesitas antes de empezar
- Un lugar abierto en Studio con
ServerScriptServicea la vista. - Saber la diferencia entre servidor y cliente: la tienes en RemoteEvents: cómo hablan el cliente y el servidor.
- Unos 15 minutos.
Paso 1: el script mínimo
Un Script normal (no un LocalScript) dentro de ServerScriptService:
local Jugadores = game:GetService("Players")
Jugadores.PlayerAdded:Connect(function(jugador)
local stats = Instance.new("Folder")
stats.Name = "leaderstats" -- este nombre es obligatorio
stats.Parent = jugador
local puntos = Instance.new("IntValue")
puntos.Name = "Puntos" -- este sale como titulo de columna
puntos.Value = 0
puntos.Parent = stats
end)
Dale a Play y pulsa Tab: ya tienes la tabla con tu nombre y un 0.

Tres cosas que conviene fijar desde ya:
leaderstatsen minúsculas.LeaderstatsoleaderStatsno funcionan y no avisan.- La carpeta va dentro del jugador, no dentro del personaje. El personaje se destruye cada vez que el jugador muere; el jugador no.
- El nombre del valor es el título de la columna.
Puntos,Monedas,Nivel… lo que pongas es lo que se ve.
Paso 2: sumar puntos desde cualquier otro script
Desde el servidor, para sumar puntos solo hay que buscar el valor y cambiarlo:
local function sumarPuntos(jugador, cantidad)
local stats = jugador:FindFirstChild("leaderstats")
if not stats then return end
local puntos = stats:FindFirstChild("Puntos")
if not puntos then return end
puntos.Value = puntos.Value + cantidad
end
Mira los dos FindFirstChild con su comprobación. Si usas jugador.leaderstats.Puntos directamente y por lo que sea todavía no existe, el script revienta con attempt to index nil. Ese error concreto está explicado en los errores de Luau más comunes.
Un ejemplo real: una moneda que al tocarla da un punto.
local moneda = script.Parent
local Jugadores = game:GetService("Players")
local cogida = false
moneda.Touched:Connect(function(parte)
if cogida then return end
local personaje = parte.Parent
local jugador = Jugadores:GetPlayerFromCharacter(personaje)
if not jugador then return end
cogida = true
sumarPuntos(jugador, 1)
moneda:Destroy()
end)
La bandera cogida no sobra: Touched se dispara varias veces por contacto y sin ella una sola moneda te da diez puntos.
Paso 3: varias columnas y su orden
Las columnas salen en el orden en que las creas, no por orden alfabético:
Jugadores.PlayerAdded:Connect(function(jugador)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = jugador
local nivel = Instance.new("IntValue")
nivel.Name = "Nivel"
nivel.Value = 1
nivel.Parent = stats
local monedas = Instance.new("IntValue")
monedas.Name = "Monedas"
monedas.Value = 0
monedas.Parent = stats
end)
Aquí sale primero Nivel y luego Monedas. Si quieres el orden al revés, cambias el orden de creación y ya está.
Qué tipo usar para cada cosa:
| Tipo | Para qué | Ojo con |
|---|---|---|
IntValue | Puntos, monedas, nivel | Solo números enteros: 3,5 se guarda como 3 |
NumberValue | Tiempos, distancias | Sale con muchos decimales si no lo redondeas |
StringValue | Rango, clan, equipo | No se puede ordenar de mayor a menor |
Paso 4: valores que no quieres enseñar
Muchas veces necesitas guardar algo del jugador que no debe salir en la tabla: experiencia, tiempo jugado, si ya cogió la recompensa del día. La solución es otra carpeta con otro nombre:
local ocultos = Instance.new("Folder")
ocultos.Name = "datos" -- cualquier nombre que no sea leaderstats
ocultos.Parent = jugador
local exp = Instance.new("IntValue")
exp.Name = "Experiencia"
exp.Parent = ocultos
Roblox solo dibuja la carpeta que se llama leaderstats. Todo lo demás queda accesible por script pero invisible.
Paso 5: que no se pierda al salir
Tal y como está, al salir del juego el jugador vuelve a cero. Para conservarlo hay que guardar en un DataStore, que tiene sus propias trampas y merece artículo aparte: cómo guardar los datos con DataStore y no perderlos.
El enganche entre las dos cosas es este, para que veas por dónde van los tiros:
Jugadores.PlayerAdded:Connect(function(jugador)
local stats = crearLeaderstats(jugador)
local guardado = cargarDatos(jugador) -- lee el DataStore
if guardado then
stats.Puntos.Value = guardado.puntos
end
end)
Jugadores.PlayerRemoving:Connect(function(jugador)
guardarDatos(jugador) -- escribe el DataStore
end)
Paso 6: la tabla global de los mejores
El leaderboard de Tab solo enseña a la gente que está en tu servidor. Para un top 10 de todo el juego hace falta un OrderedDataStore, que es un DataStore que sabe ordenar:
local Datos = game:GetService("DataStoreService")
local tabla = Datos:GetOrderedDataStore("TopPuntos")
-- Al salir, apuntamos su puntuacion
local ok, err = pcall(function()
tabla:SetAsync(tostring(jugador.UserId), puntos.Value)
end)
-- Para leer el top 10
local ok2, paginas = pcall(function()
return tabla:GetSortedAsync(false, 10) -- false = de mayor a menor
end)
if ok2 then
for puesto, entrada in ipairs(paginas:GetCurrentPage()) do
print(puesto, entrada.key, entrada.value)
end
end
Ese entrada.key es el UserId en texto. Para sacar el nombre a partir de él usas Jugadores:GetNameFromUserIdAsync(id), y guarda el resultado en una tabla: es una llamada a los servidores de Roblox y no quieres hacerla cada vez que refresques la tabla.
Constrúyelo aquí
Elige tus columnas y llévate el script
Monta tu leaderstats: nombre, tipo y si sale o no en la tabla. Abajo se genera el código para pegar en ServerScriptService.
Así se vería al pulsar Tab
Tu script
Errores habituales
La tabla no aparece al pulsar Tab
Casi siempre es el nombre. Tiene que ser leaderstats exacto: minúsculas, una sola palabra, sin espacios. Compruébalo en el explorador con el juego corriendo.
Aparece la tabla pero está vacía
Creaste la carpeta pero no metiste ningún valor dentro, o los metiste dentro del jugador en vez de dentro de la carpeta. En el explorador, los valores tienen que colgar de leaderstats, no del jugador.
Los puntos suben en mi pantalla pero nadie más los ve
Estás cambiando el valor desde un LocalScript. El cliente puede cambiar cosas en su copia del mundo, pero eso no viaja a los demás. Los leaderstats se tocan siempre desde el servidor; si el cambio nace de un botón del jugador, pasa por un RemoteEvent, como se explica en RemoteEvents: cómo hablan el cliente y el servidor.
Se queda en un número raro y no sube más
Un IntValue aguanta hasta 2.147.483.647. Si tu juego genera cifras más grandes, usa un NumberValue y formatea el texto tú (1,2 M · 3,4 B) en la interfaz.
El personaje reaparece y los puntos se van a cero
Creaste la carpeta dentro del personaje en vez de dentro del jugador. PlayerAdded te da el jugador: la carpeta va ahí y sobrevive a las muertes.
attempt to index nil with 'Puntos'
El script intentó leer el valor antes de que existiera, normalmente porque otro script se adelantó al que crea la carpeta. Usa jugador:WaitForChild("leaderstats"):WaitForChild("Puntos") en el que llega tarde.
Preguntas frecuentes
¿Puedo poner un icono o cambiar los colores de la tabla?
La tabla de Tab no se puede personalizar. Si quieres control sobre el aspecto, se desactiva con SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false) desde un LocalScript y te haces tu propia interfaz con un ScreenGui.
¿Cuántas columnas puedo poner?
No hay un límite duro, pero pasadas tres o cuatro la tabla se come la pantalla en móvil, que es donde juega la mayoría. Deja en leaderstats lo que interesa comparar y el resto en una carpeta oculta.
¿Se puede ordenar la tabla por una columna concreta?
La tabla de Roblox ordena por la primera columna numérica. Si necesitas otro criterio, toca hacerse la interfaz.
¿Cómo evito que un jugador se haga trampas con los puntos?
Que el valor solo lo cambien scripts del servidor. Un exploit puede modificar el número que ve en su pantalla, pero como el servidor tiene el suyo, al guardar o al comprobar cualquier cosa se usa el bueno.
Última revisión: 1 de septiembre de 2026





Deja una respuesta