Prerequisites
- A GMod server at VeryCloud
- An accessible MySQL/MariaDB DB
- Access to Files in Wisp
Step 1: Choose the mysqloo version
On VeryCloud Wisp (Linux x64), grab gmsv_mysqloo_linux64.dll (the .dll extension stays under Linux — GMod convention).
Step 2: Upload the binary
In Wisp → Files → /garrysmod/lua/bin/:
- Create the folder if it doesn't exist
- Upload
gmsv_mysqloo_linux64.dll
Restart.
Step 3: Verify load
At boot, console:
require("mysqloo")
No error = loaded. Otherwise check architecture (32 vs 64 bit) and filename.
Step 4: Prepare the DB
CREATE DATABASE gmod_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'gmod_user'@'IP_OF_GMOD_SERVER' IDENTIFIED BY 'solid_password_16_chars';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER, DROP
ON gmod_db.*
TO 'gmod_user'@'IP_OF_GMOD_SERVER';
FLUSH PRIVILEGES;
⚠️ Never use
%for host. Specify the GMod server IP (from Wisp → Network).
Step 5: First Lua script with mysqloo
Create /garrysmod/lua/autorun/server/db_init.lua:
require("mysqloo")
local DB_HOST = "your.mysql.host"
local DB_USER = "gmod_user"
local DB_PASS = "solid_password_16_chars"
local DB_NAME = "gmod_db"
local DB_PORT = 3306
DB = mysqloo.connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT)
function DB:onConnected()
print("[DB] MySQL connection OK")
end
function DB:onConnectionFailed(err)
print("[DB] Connection failed: " .. err)
end
DB:connect()
Restart. Should print [DB] MySQL connection OK.
Step 6: First query
local q = DB:query("CREATE TABLE IF NOT EXISTS players (\
steamid VARCHAR(20) PRIMARY KEY,\
name VARCHAR(64),\
money INT DEFAULT 500,\
last_login DATETIME\
)")
function q:onSuccess()
print("[DB] players table created")
end
function q:onError(err)
print("[DB] Table creation error: " .. err)
end
q:start()
All mysqloo queries are async: declare onSuccess and onError callbacks, then :start().
Step 7: Common patterns
SELECT:
local function GetPlayerMoney(ply, cb)
local q = DB:query(string.format(
"SELECT money FROM players WHERE steamid = %s",
DB:escape(ply:SteamID())
))
function q:onSuccess(data)
cb(tonumber(data[1] and data[1].money) or 0)
end
function q:onError(err)
print("[DB] error: " .. err)
cb(0)
end
q:start()
end
Prepared statement:
local stmt = DB:prepare("UPDATE players SET money = ? WHERE steamid = ?")
stmt:setNumber(1, 1000)
stmt:setString(2, ply:SteamID())
function stmt:onSuccess() print("[DB] Update OK") end
function stmt:onError(err) print("[DB] Error: " .. err) end
stmt:start()
Always prefer prepared statements — performance + SQL injection protection.
Step 8: Auto-reconnection
mysqloo handles silent disconnects poorly (MySQL idle timeout). Reconnection pattern:
function DB:onConnectionFailed(err)
print("[DB] Connection lost, retry in 5s...")
timer.Simple(5, function() DB:connect() end)
end
Or periodic ping to keep alive:
timer.Create("DB_Ping", 60, 0, function()
local q = DB:query("SELECT 1")
function q:onError(err)
print("[DB] Ping failed, reconnecting...")
DB:connect()
end
q:start()
end)
Step 9: DarkRP integration
DarkRP uses MySQLite on top of mysqloo (or SQLite). Configure in /garrysmod/addons/darkrpmodification/lua/darkrp_config/mysql.lua. Other DarkRP-compatible addons automatically use your connection.
Step 10: Security
- Dedicated MySQL account per app/server
- Source IP restricted (never
%) - Long password, never committed to Git
- TLS for MySQL if the connection leaves the datacenter
- Regular DB backups (mysqldump cron + offsite)
Troubleshooting
Module not found: mysqloo — wrong location (must be /garrysmod/lua/bin/), wrong arch.
Access denied for user — wrong password, source IP not in GRANTs.
Can't connect to MySQL server — port 3306 firewall, GMod server IP changed.
Slow queries / freezes — not using async (verify :start() and callbacks).
Useful commands
lua_run print(DB:status() == mysqloo.DATABASE_CONNECTED)
lua_run local q = DB:query("SHOW TABLES") q.onSuccess = function(self, data) PrintTable(data) end q:start()
DB:escape(text)
Conclusion
mysqloo = cornerstone of any serious GMod server: persistent economy, player stats, bans, logs. 30 min setup with a prepared DB. Always async, always prepared statements for user inputs. Once in place, all your addons (DarkRP, ULib MySQL, custom) benefit.
Going further: multi-connection pools for performance, MySQLite (SQLite/MySQL abstraction), monitor DB latency gamemode-side.


















