For the complete documentation index, see llms.txt. This page is also available as Markdown.

Website: Kill Log Queries

Step-by-step guide for web developers - query the PvP Kill Log table for recent-kill feeds, top fights, guild and map stats, build an all-time PvP ladder (kills, deaths, assists, damage), and decode f

The Kill Log writes one row per PvP death into dbo.PvPKillLog. This guide shows how to use that table on a website: a live kill feed, top fights, guild and map stats, an all-time PvP ladder with kills, deaths, assists and damage, and a fight recap page.

Read this first: the table is a rolling window

The table does not keep every kill forever. Each character keeps its last KeepPerChar rows (default 50) as victim and as killer. A row is deleted once both players have more than 50 newer fights.

What that means:

Use
Query the table directly?

Last kills feed, top fights this week, a character's recent fights

Yes - see Recent queries

All-time kills / deaths / damage ladder

No - counts drop as old rows are deleted. Use the ladder table

The table

Column
Type
Meaning

Id

int, identity

Grows by 1 per row. Never reused

KillTime

datetime

Time of death (SQL Server's clock)

KillType

tinyint

0 world, 1 duel, 2 siege, 3 event, 4 gens, 5 guild war

Victim / Killer

varchar(10)

Character names. A kill by a summon is credited to its owner

VictimGuild / KillerGuild

varchar(8)

Guild at the time, '' = none

VictimClass / KillerClass

tinyint

Class code, same values as Character.Class

VictimLevel / KillerLevel

smallint

Level (not master level)

MapNumber, MapX, MapY

tinyint

Where the victim died

FightMs

bigint

Fight length in milliseconds

TotalDmg

bigint

Damage the victim took in the fight, HP + SD, from all attackers

TopSkill

int

Skill that did the most damage (from any attacker). 0 = basic attack, 65535 = several merged, 65534 = poison / bleed, 65533 = reflect

AssistCount

tinyint

Attackers other than the killer

VictimKeep / KillerKeep

bit

Internal window flags. Ignore

Detail

varbinary

Per-attacker and per-skill totals, last 32 hits. See Fight details

Indexes exist on Victim and Killer. For time-based pages add one more (safe, the game does not care):

Skill names come from Skill.txt (skill number → name). Class codes are the same as in Character.Class, which your website already shows.

Recent queries

Run these straight on PvPKillLog. Use parameters for names.

Kill feed (last 20):

Top killers, last 7 days (no duels):

Short periods (day, week) are accurate unless a player fights more than KeepPerChar times in that period. For longer periods use the ladder table.

Biggest fights (most damage taken before dying):

Longest fights: same query, ORDER BY FightMs DESC.

Character page (last fights of one character):

Nemesis (who killed this character the most):

Guild war / siege table:

PvP hot spots (deaths per map):

Most deadly skills:

All-time ladder

Because old rows are deleted, an all-time ladder needs its own table. A stored procedure reads every new row since its last run and adds it to the totals. It also reads the Detail column, so the ladder gets damage dealt and assists, which are not in the plain columns.

Ladder column
Comes from

Kills

Rows where the character is Killer

Deaths

Rows where the character is Victim

Assists

Fights where the character hit the victim but did not land the kill

DamageDone

HP + SD damage the character dealt to players who then died

DamageTaken

TotalDmg of the character's deaths

BiggestHit

Biggest single hit (HP + SD) in any counted fight

LastFight

Time of the last counted fight

Damage in fights the target survived is not recorded by the game, so it cannot be counted.

Install (once)

Run this against the muonline database in SQL Server Management Studio. It only adds new objects (WEB_ prefix); it changes nothing the game uses.

Before running, edit the KillType IN (...) line to choose what counts. The default leaves out duels (1), because friends can farm duel kills.

Run it once by hand to count the rows already in the table:

Keep it updated

Run EXEC dbo.WEB_PvPLadderUpdate every 1-5 minutes. Each run only reads new rows, so it is cheap. Running it twice in a row counts nothing twice.

Pick one way:

Way
How

SQL Server Agent (not in Express)

New job, one step EXEC dbo.WEB_PvPLadderUpdate, schedule every 1 minute

Windows Task Scheduler

Every 1 minute: sqlcmd -S . -E -d muonline -Q "EXEC dbo.WEB_PvPLadderUpdate"

Website cron

Your site's scheduler runs the EXEC

Ladder queries

Top killers:

Damage ladder: ORDER BY l.DamageDone DESC. Biggest hit: ORDER BY l.BiggestHit DESC. Best K/D (minimum 20 kills, so one lucky kill does not top it):

Season reset: TRUNCATE TABLE dbo.WEB_PvPLadder. Do not reset WEB_PvPLadderState, or old kills are counted again.

Fight details

The Detail column holds the full recap the game shows in the Kill Log window. All numbers are little-endian. Use it for a fight recap page.

Part
Size
Count

Head

12

1

Attacker

32

AttackerCount (max 8)

Skill row

21

SkillCount (max 48)

Hit

14

HitCount (max 32), oldest first

Head:

Offset
Size
Field

0

1

Version. Only 1 exists

1

1

AttackerCount

2

1

SkillCount

3

1

HitCount

4

4

Victim max HP

8

4

Victim max SD

Attacker (32 bytes):

Offset
Size
Field

0

10

Name, zero-padded (no zero when 10 characters long)

10

8

Guild, zero-padded

18

1

Class code

19

2

Level

21

4

HP damage dealt

25

4

SD damage dealt

29

2

Hits

31

1

Flags: 1 = landed the kill, 2 = "others" (more than 8 attackers merged into one entry)

Skill row (21 bytes):

Offset
Size
Field

0

1

Attacker (index into the attacker list, 0 = first)

1

2

Skill. 0 basic attack, 65535 other skills merged, 65534 poison / bleed, 65533 reflect

3

4

HP damage

7

4

SD damage

11

2

Hits

13

2

Critical hits

15

2

Excellent hits

17

4

Biggest single hit (HP + SD)

Hit (14 bytes):

Offset
Size
Field

0

1

Attacker index

1

2

Skill

3

4

HP damage

7

4

SD damage

11

1

Flags: 1 critical, 2 excellent, 4 ignore defense, 8 double, 16 triple, 32 combo, 64 reflect, 128 poison / bleed

12

2

Time before the death, in 1/100 seconds

unpack with an offset needs PHP 7.1+. Read Detail with PDO::SQLSRV_ENCODING_BINARY so it comes back as raw bytes.

Useful numbers for a recap page:

  • Each attacker's share: (hp + sd) / sum of all attackers' (hp + sd).

  • Skill share: (skill.hp + skill.sd) / TotalDmg.

  • "Killing blow": the last entry of hits.

Important Behavior

  • Only player-kills-player deaths are recorded. No monster kills, no suicides.

  • What gets recorded depends on KillLog.xml: disabled <Types> and fights under MinTotalDamage never reach the table. The ladder can only count what is there.

  • Duel farming. The ladder default skips duels. Watch for pairs that kill each other again and again:

  • Character rename. Rows keep the old name. The ladder starts a new line for the new name.

  • Time. KillTime is the SQL Server machine's local time.

  • Free plugin, no license check: if Enabled="1" in KillLog.xml, rows are written.

Common Issues

Last updated