Wikipedia MTA

Guardar datos de jugadores en MTA:SA con MySQL: conexión y consultas básicas

Cualquier gamemode serio necesita persistir datos: dinero, inventario, nivel, propiedades. MTA:SA se conecta de forma nativa a bases de datos MySQL desde el lado del servidor. Esta guía cubre lo esencial para empezar.

1. Conectarse a la base de datos

local connection = dbConnect("mysql", "dbname=mi_gamemode;host=127.0.0.1", "usuario", "contraseña")
Esta conexión normalmente se crea una sola vez al iniciar el recurso y se guarda en una variable accesible desde el resto del script.

Ten en cuenta que necesitas un hosting que incluya base de datos MySQL habilitada para tu servidor de MTA; no todos los planes de hosting genéricos la incluyen configurada de forma directa. Un hosting pensado específicamente para MTA:SA suele resolver esto sin configuración adicional de tu parte.

2. Crear la tabla (una sola vez)

dbExec(connection, "CREATE TABLE IF NOT EXISTS jugadores (serial VARCHAR(32) PRIMARY KEY, dinero INT DEFAULT 0, nivel INT DEFAULT 1)")

3. Guardar datos de un jugador

addEventHandler("onPlayerQuit", root, function()
    local serial = getPlayerSerial(source)
    local dinero = getElementData(source, "dinero") or 0
    dbExec(connection, "UPDATE jugadores SET dinero = ? WHERE serial = ?", dinero, serial)
end)
Usar ? como marcador de posición (parámetros preparados) en lugar de concatenar los valores directamente en el texto de la consulta es fundamental: evita errores de sintaxis con caracteres especiales y, sobre todo, evita inyección SQL si algún valor viene de una fuente no confiable.

4. Leer datos al conectarse

Las consultas de lectura son asíncronas: se lanzan con dbQuery y el resultado se recoge con dbPoll.

addEventHandler("onPlayerJoin", root, function()
    local serial = getPlayerSerial(source)
    local queryHandle = dbQuery(connection, "SELECT * FROM jugadores WHERE serial = ?", serial)
    local result = dbPoll(queryHandle, -1)


    if result and #result > 0 then
        setElementData(source, "dinero", result[1].dinero)
        setElementData(source, "nivel", result[1].nivel)
    else
        dbExec(connection, "INSERT INTO jugadores (serial, dinero, nivel) VALUES (?, 100, 1)", serial)
    end
end)
Este patrón (buscar al jugador; si no existe, crearlo con valores por defecto) es el más común para sistemas de cuentas persistentes.

Buenas prácticas con bases de datos en MTA

  • Nunca concatenes valores directamente en el SQL ("... WHERE serial = '" .. serial .. "'"); usa siempre parámetros (?) como en los ejemplos anteriores.
  • No guardes datos en cada frame ni en cada evento menor: guarda al desconectarse, periódicamente (por ejemplo cada 5 minutos con un timer), o cuando ocurre un cambio importante, nunca de forma constante.
  • Haz respaldos periódicos de la base de datos, independientes del respaldo de código (ver nuestro artículo sobre backups y control de versiones). Perder la base de datos de un servidor con progreso de jugadores reales es uno de los peores escenarios posibles para una comunidad.
Aporte por:
Nicolas ECM
Udemy

Curso Programación en LUA para MTA

Aprende a programar desde 0 hasta avanzado con ejercicios prácticos

🔥 Ver Curso en Udemy