How to Create Real-Time Ranking Website for MU Server
Build a live-updating ranking portal for MU Online S6 servers — covering all 6 classes, guild boards, and database architecture.
Why Real-Time Rankings Change Everything
In a MU Online Season 6 server, competitive progression is the engine that keeps the community alive. Static rankings — refreshed once a day or updated manually — miss the moment: a Blade Master who just overtook a rival in level sees nothing until tomorrow, and the energy of that achievement dissipates.
A real-time ranking board transforms that experience. A player grinding in Tarkan or Icarus opens the portal and watches their position climb. Guilds monitor the standings while the Land of Trials event is still active. The website stops being a static showcase and becomes an extension of the game itself.
This tutorial covers the full stack: safe database reads from the MU server, a backend API, an auto-refreshing frontend, and proper display of all six S6 classes.
System Architecture Overview
Before writing any code, map out the data flow:
MU Database (MySQL / MSSQL)
↓ read-only access (SELECT only)
Backend API (Node.js / PHP / Python)
↓ JSON endpoint
Frontend (HTML + JS)
↓ AJAX polling or WebSocket
Ranking Table in Browser
↓ refreshes every 30–60 s
Player sees their live position
Keeping the layers separated means the frontend never talks directly to the database. All business logic — filtering, validation, pagination — lives in the backend before data is ever exposed publicly.
MU S6 Database Structure
MU Online S6 stores characters in the Character table (the exact name may vary by emulator). The columns most relevant to ranking are:
| Column | Type | Description |
|---|---|---|
Name | VARCHAR | Character name |
Class | TINYINT | Numeric class/job code |
cLevel | SMALLINT | Current level (1–400 in standard S6) |
Resets | INT | Reset count (if the server uses resets) |
GuildName | VARCHAR | Character's guild |
PkCount | INT | Player-kill counter |
Strength, Dexterity, Vitality, Energy | INT | Core stats |
Leadership | INT | CMD stat — exclusive to Dark Lord / Lord Emperor |
The Class field stores a numeric code. Common S6 values:
0 → Dark Knight
1 → Blade Knight (DK 1st evolution)
2 → Blade Master (DK Master Class)
16 → Dark Wizard
17 → Soul Master (DW 1st evolution)
18 → Grand Master (DW Master Class)
32 → Elf (Fairy Elf)
33 → Muse Elf (Elf 1st evolution)
34 → High Elf (Elf Master Class)
48 → Magic Gladiator → Duel Master (no 1st/2nd quest, no Wing L1)
64 → Dark Lord → Lord Emperor (exclusive CMD / Leadership stat)
80 → Summoner
81 → Bloody Summoner (Summoner 1st evolution)
82 → Dimension Master (Summoner Master Class)
Building the Ranking API
The example below uses Node.js with mysql2, but the same logic applies to PHP (PDO) or Python (aiomysql) with minimal changes.
// ranking-api.js — GET /api/ranking/players
const mysql = require('mysql2/promise');
const CLASS_NAMES = {
0: 'Dark Knight', 1: 'Blade Knight', 2: 'Blade Master',
16: 'Dark Wizard', 17: 'Soul Master', 18: 'Grand Master',
32: 'Elf', 33: 'Muse Elf', 34: 'High Elf',
48: 'Magic Gladiator → Duel Master',
64: 'Dark Lord → Lord Emperor',
80: 'Summoner', 81: 'Bloody Summoner', 82: 'Dimension Master',
};
async function getRanking(limit = 100, offset = 0) {
const conn = await mysql.createConnection(process.env.DB_URL_READONLY);
const [rows] = await conn.execute(`
SELECT
Name,
Class,
cLevel AS level,
Resets AS resets,
GuildName AS guild,
Leadership AS cmd_stat
FROM Character
WHERE CtlCode = 0 -- exclude GMs and suspended accounts
ORDER BY Resets DESC, cLevel DESC, Name ASC
LIMIT ? OFFSET ?
`, [limit, offset]);
await conn.end();
return rows.map((row, i) => ({
rank: offset + i + 1,
name: row.Name,
class: CLASS_NAMES[row.Class] ?? `Class ${row.Class}`,
level: row.level,
resets: row.resets,
guild: row.guild || '—',
cmd_stat: row.cmd_stat ?? null, // null for classes without CMD
}));
}
The query orders by Resets DESC, then Level DESC — the standard criterion on S6 servers that use the reset system. On servers without resets, remove the Resets column from the ORDER BY clause.
Frontend with Auto-Refresh
The frontend consumes the endpoint and updates the table without a full page reload. A 45-second interval is a good balance between data freshness and server load.
<!-- ranking-table.html (relevant excerpt) -->
<table id="ranking-table">
<thead>
<tr>
<th>#</th><th>Character</th><th>Class</th>
<th>Level</th><th>Resets</th><th>Guild</th>
</tr>
</thead>
<tbody id="ranking-body"></tbody>
</table>
<span id="last-update"></span>
<script>
const INTERVAL_MS = 45_000;
async function fetchRanking() {
const res = await fetch('/api/ranking/players?limit=100');
const data = await res.json();
const tbody = document.getElementById('ranking-body');
tbody.innerHTML = data.map(p => `
<tr class="class-${p.class.toLowerCase().replace(/[\s→]+/g, '-')}">
<td>${p.rank}</td>
<td>${p.name}</td>
<td>${p.class}</td>
<td>${p.level}</td>
<td>${p.resets}</td>
<td>${p.guild}</td>
</tr>
`).join('');
document.getElementById('last-update').textContent =
'Updated: ' + new Date().toLocaleTimeString('en-US');
}
fetchRanking();
setInterval(fetchRanking, INTERVAL_MS);
</script>
name → rank pairs. A green up-arrow or red down-arrow next to the rank number significantly boosts player engagement.Specialized Boards: Guild, PK, and Wings
Beyond the main character ranking, dedicated leaderboards for specific criteria keep different player segments interested:
Guild Ranking — group by GuildName and aggregate member resets or levels. Guilds that include a Dark Lord with high Leadership (CMD) have more summon slots, which matters strategically in Crywolf Fortress and Land of Trials events. Surfacing CMD totals per guild gives context that a simple level sum cannot.
PK Ranking — order by PkCount DESC. Display the PK status (Murderer, Outlaw, etc.) next to each name. This board drives community drama in the best possible way and encourages the hunter-vs-hunted dynamic between players.
Wing L3 Prestige Board — a Wing Level 3 is the most prestigious equipment piece in S6. Crafting one requires a Wing L2, three Loch's Feathers, and a Jewel of Creation. Loch's Feather drops exclusively from Balgass — the final boss of the Crywolf event — and only when the event fails, meaning the monsters successfully destroy the Altar of Gods. That rare drop condition makes Wing L3 owners a genuine elite. A dedicated board celebrating these characters drives Crywolf participation and creates aspirational goals.
Caching and Performance
On servers with hundreds of simultaneous players, querying the database on every ranking page request is not scalable. A simple cache layer solves this:
User request
↓
Cache (Redis or in-memory) → still valid → return cached JSON
↓ (cache expired)
Query the database
↓
Refresh cache → return JSON
Even an in-memory cache (a JavaScript object or PHP array) dramatically reduces database load. Ranking data does not need to be accurate to the millisecond — a 30 to 60 second freshness window is imperceptible to the player and can eliminate dozens of queries per minute.
Final Considerations
A well-built ranking portal is one of the most effective tools for keeping a community invested in a server. The six classes of S6 — each with their distinct characteristics, from the Dark Lord's exclusive CMD stat to the Magic Gladiator's lack of Wing L1 — deserve clear and accurate presentation in the frontend so players actually understand what they are looking at.
Read-only database access, a cache layer, and clean pagination ensure the portal remains stable during peak hours without ever threatening the integrity of the game's database.
Perguntas frequentes
Which classes appear in the MU S6 ranking?
All six playable classes: Dark Knight (→ Blade Knight → Blade Master), Dark Wizard (→ Soul Master → Grand Master), Elf (→ Muse Elf → High Elf), Magic Gladiator (→ Duel Master, no 1st/2nd quest, no Wing L1), Dark Lord (→ Lord Emperor, exclusive CMD stat), and Summoner (→ Bloody Summoner → Dimension Master). The portal should display each character's current job by reading the class code from the database.
How often should a real-time ranking refresh?
On active servers a 30–60 second AJAX polling interval is a solid balance. If your database supports push notifications (e.g., PostgreSQL LISTEN/NOTIFY or MySQL triggers with a WebSocket bridge), you can push updates in under 5 seconds without hammering the server.
Should a guild ranking display the Dark Lord's CMD stat?
Absolutely. CMD (Leadership) is exclusive to the Dark Lord and Lord Emperor and governs how many units the class can summon. It is a strategic differentiator worth surfacing in guild rankings, as it signals the support capacity of the guild's leader.
Can I rank characters by Wing level?
Yes, and it makes a great prestige column. In S6 a Wing Level 3 requires Wing L2 + 3 Loch's Feathers + Jewel of Creation. Loch's Feather drops from Balgass only when the Crywolf event FAILS — making Wing L3 rare and a meaningful ranking criterion.